Merge branch 'master' into snyk-upgrade-afb4b30e57500d72a09e8b1cc98e999a
This commit is contained in:
commit
ad03aadd44
|
@ -1,7 +1,13 @@
|
|||
# Changelog
|
||||
|
||||
## 1.12.0
|
||||
* Post length preference is now part of the profile match score
|
||||
* Improved kink match scoring
|
||||
* Middle click a link to pin or unpin preview
|
||||
|
||||
|
||||
## 1.11.0
|
||||
* Kinks are now part of the profile matching score
|
||||
* Kinks are now part of the profile match score
|
||||
* Merged with the latest official F-Chat codebase
|
||||
* Fixed broken `[collapse]` when wrapped in `[heading]`
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Download
|
||||
[Windows](https://github.com/mrstallion/fchat-rising/releases/download/v1.11.0/F-Chat-Rising-1.11.0-win.exe) (75 MB)
|
||||
| [MacOS](https://github.com/mrstallion/fchat-rising/releases/download/v1.11.0/F-Chat-Rising-1.11.0-macos.dmg) (76 MB)
|
||||
| [Linux](https://github.com/mrstallion/fchat-rising/releases/download/v1.11.0/F-Chat-Rising-1.11.0-linux.AppImage) (76 MB)
|
||||
[Windows](https://github.com/mrstallion/fchat-rising/releases/download/v1.12.0/F-Chat-Rising-1.12.0-win.exe) (75 MB)
|
||||
| [MacOS](https://github.com/mrstallion/fchat-rising/releases/download/v1.12.0/F-Chat-Rising-1.12.0-macos.dmg) (76 MB)
|
||||
| [Linux](https://github.com/mrstallion/fchat-rising/releases/download/v1.12.0/F-Chat-Rising-1.12.0-linux.AppImage) (76 MB)
|
||||
|
||||
|
||||
# F-Chat Rising
|
||||
|
@ -93,6 +93,7 @@ This repository contains a heavily customized version of the mainline F-Chat 3.0
|
|||
* Sexual preference
|
||||
* Dominance preference
|
||||
* Human/anthro preference
|
||||
* Post length preference
|
||||
* Non-custom kinks
|
||||
* Species
|
||||
1. Maching for non-binary genders relies on kinks. For example, if your non-binary character has a preference for females, make sure 'females' are listed as a favorite kink.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@mouseover.prevent="show()"
|
||||
@mouseenter.prevent="show()"
|
||||
@mouseleave.prevent="dismiss()"
|
||||
@click.middle.prevent="toggleStickyness()"
|
||||
@click.middle.prevent.stop="toggleStickyness()"
|
||||
@click.right.passive="dismiss(true)"
|
||||
@click.left.passive="dismiss(true)"
|
||||
><img :src="`${Utils.staticDomain}images/avatar/${character.toLowerCase()}.png`" class="character-avatar icon" :title="character" :alt="character" v-once></a>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
@mouseover.prevent="show()"
|
||||
@mouseenter.prevent="show()"
|
||||
@mouseleave.prevent="dismiss()"
|
||||
@click.middle.prevent="toggleStickyness()"
|
||||
@click.middle.prevent.stop="toggleStickyness()"
|
||||
>{{text}}</a>
|
||||
<span
|
||||
class="link-domain bbcode-pseudo"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<chat v-else></chat>
|
||||
<chat ref="chatview" v-else></chat>
|
||||
<modal :action="l('chat.disconnected.title')" :buttonText="l('action.cancel')" ref="reconnecting" @submit="cancelReconnect"
|
||||
:showCancel="false" buttonClass="btn-danger">
|
||||
<div class="alert alert-danger" v-show="error">{{error}}</div>
|
||||
|
@ -220,6 +220,10 @@
|
|||
|
||||
core.connection.connect(this.selectedCharacter.name);
|
||||
}
|
||||
|
||||
getChatView(): ChatView | undefined {
|
||||
return this.$refs['chatview'] as ChatView;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<a v-for="conversation in conversations.privateConversations" href="#" @click.prevent="conversation.show()"
|
||||
:class="getClasses(conversation)" :data-character="conversation.character.name" data-touch="false"
|
||||
class="list-group-item list-group-item-action item-private" :key="conversation.key"
|
||||
@click.middle.prevent="conversation.close()">
|
||||
@click.middle.prevent.stop="conversation.close()">
|
||||
<img :src="characterImage(conversation.character.name)" v-if="showAvatars"/>
|
||||
<div class="name">
|
||||
<span>{{conversation.character.name}}</span>
|
||||
|
@ -54,7 +54,7 @@
|
|||
<div class="list-group conversation-nav" ref="channelConversations">
|
||||
<a v-for="conversation in conversations.channelConversations" href="#" @click.prevent="conversation.show()"
|
||||
:class="getClasses(conversation)" class="list-group-item list-group-item-action item-channel" :key="conversation.key"
|
||||
@click.middle.prevent="conversation.close()">
|
||||
@click.middle.prevent.stop="conversation.close()">
|
||||
<span class="name">{{conversation.name}}</span>
|
||||
<span>
|
||||
<span v-if="conversation.hasAutomatedAds()" class="fas fa-ad" :class="{'active': conversation.isSendingAutomatedAds()}" aria-label="Toggle ads"
|
||||
|
@ -129,6 +129,7 @@
|
|||
import PrivateConversation = Conversation.PrivateConversation;
|
||||
import * as _ from 'lodash';
|
||||
import NoteStatus from '../site/NoteStatus.vue';
|
||||
// import { EventBus } from './preview/event-bus';
|
||||
|
||||
const unreadClasses = {
|
||||
[Conversation.UnreadState.None]: '',
|
||||
|
@ -366,6 +367,10 @@
|
|||
isColorblindModeActive(): boolean {
|
||||
return core.state.settings.risingColorblindMode;
|
||||
}
|
||||
|
||||
getImagePreview(): ImagePreview | undefined {
|
||||
return this.$refs['imagePreview'] as ImagePreview;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<!-- Linebreaks inside this template will break BBCode views -->
|
||||
<template><span :class="userClass" v-bind:bbcodeTag.prop="'user'" v-bind:character.prop="character" v-bind:channel.prop="channel" @mouseover.prevent="show()" @mouseenter.prevent="show()" @mouseleave.prevent="dismiss()" @click.middle.prevent="toggleStickyness()" @click.right.passive="dismiss(true)" @click.left.passive="dismiss(true)"><span v-if="!!statusClass" :class="statusClass"></span><span v-if="!!rankIcon" :class="rankIcon"></span>{{character.name}}<span v-if="!!matchClass" :class="matchClass">{{getMatchScoreTitle(matchScore)}}</span></span></template>
|
||||
<template><span :class="userClass" v-bind:bbcodeTag.prop="'user'" v-bind:character.prop="character" v-bind:channel.prop="channel" @mouseover.prevent="show()" @mouseenter.prevent="show()" @mouseleave.prevent="dismiss()" @click.middle.prevent.stop="toggleStickyness()" @click.right.passive="dismiss(true)" @click.left.passive="dismiss(true)"><span v-if="!!statusClass" :class="statusClass"></span><span v-if="!!rankIcon" :class="rankIcon"></span>{{character.name}}<span v-if="!!matchClass" :class="matchClass">{{getMatchScoreTitle(matchScore)}}</span></span></template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Hook, Prop, Watch } from '@f-list/vue-ts';
|
||||
import Vue from 'vue';
|
||||
import {Channel, Character} from '../fchat';
|
||||
import { Score, Scoring } from '../learn/matcher';
|
||||
import { Score } from '../learn/matcher';
|
||||
import core from './core';
|
||||
import { EventBus } from './preview/event-bus';
|
||||
import { kinkMatchWeights } from '../learn/matcher-types';
|
||||
import { kinkMatchWeights, Scoring } from '../learn/matcher-types';
|
||||
|
||||
|
||||
export function getStatusIcon(status: Character.Status): string {
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import { Component, Hook, Prop } from '@f-list/vue-ts';
|
||||
import {CreateElement, default as Vue, VNode, VNodeChildrenArrayContents} from 'vue';
|
||||
import {Channel} from '../fchat';
|
||||
import { Score, Scoring } from '../learn/matcher';
|
||||
import { Score } from '../learn/matcher';
|
||||
import {BBCodeView} from '../bbcode/view';
|
||||
import {formatTime} from './common';
|
||||
import core from './core';
|
||||
import {Conversation} from './interfaces';
|
||||
import UserView from './UserView.vue';
|
||||
import { Scoring } from '../learn/matcher-types';
|
||||
|
||||
const userPostfix: {[key: number]: string | undefined} = {
|
||||
[Conversation.Message.Type.Message]: ': ',
|
||||
|
|
|
@ -169,8 +169,16 @@
|
|||
|
||||
const eventUrl = this.jsMutator.mutateUrl(this.negotiateUrl(eventData.url as string || ''));
|
||||
|
||||
if ((this.url === eventUrl) && (this.visible))
|
||||
if (
|
||||
((eventData.force === true) || (this.url === eventUrl))
|
||||
&& (this.visible)
|
||||
) {
|
||||
this.sticky = !this.sticky;
|
||||
|
||||
if (eventData.force) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ gem "jekyll-theme-slate", "~> 0.1.1"
|
|||
|
||||
# If you have any plugins, put them here!
|
||||
group :jekyll_plugins do
|
||||
gem "jekyll-feed", "~> 0.13", ">= 0.13.0"
|
||||
gem "jekyll-feed", "~> 0.15", ">= 0.15.1"
|
||||
end
|
||||
|
||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
|
|
|
@ -50,7 +50,7 @@ theme: jekyll-theme-slate
|
|||
changelog: https://github.com/mrstallion/fchat-rising/blob/master/CHANGELOG.md
|
||||
|
||||
download:
|
||||
version: 1.11.0
|
||||
version: 1.12.0
|
||||
|
||||
url: https://github.com/mrstallion/fchat-rising/releases/download/v%VERSION%/F-Chat-Rising-%VERSION%-%PLATFORM_TAIL%
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div @mouseover="onMouseOver" id="page" style="position:relative;padding:5px 10px 10px" :class="getThemeClass()" @auxclick.prevent>
|
||||
<div @mouseover="onMouseOver" id="page" style="position:relative;padding:5px 10px 10px" :class="getThemeClass()" @auxclick.prevent @click.middle="unpinUrlPreview">
|
||||
<div v-html="styling"></div>
|
||||
<div v-if="!characters" style="display:flex; align-items:center; justify-content:center; height: 100%;">
|
||||
<div class="card bg-light" style="width: 400px;">
|
||||
|
@ -138,6 +138,7 @@
|
|||
|
||||
import BBCodeTester from '../bbcode/Tester.vue';
|
||||
|
||||
// import ImagePreview from '../chat/preview/ImagePreview.vue';
|
||||
// import Bluebird from 'bluebird';
|
||||
// import Connection from '../fchat/connection';
|
||||
// import Notifications from './notifications';
|
||||
|
@ -555,6 +556,21 @@
|
|||
async openDefinitionWithWikipedia(): Promise<void> {
|
||||
(this.$refs.wordDefinitionLookup as any).setMode('wikipedia');
|
||||
}
|
||||
|
||||
|
||||
unpinUrlPreview(e: Event): void {
|
||||
const imagePreview = (this.$refs['chat'] as Chat)?.getChatView()?.getImagePreview();
|
||||
|
||||
// const imagePreview = this.$refs['imagePreview'] as ImagePreview;
|
||||
|
||||
if ((imagePreview) && (imagePreview.isVisible()) && (imagePreview.sticky)) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
EventBus.$emit('imagepreview-toggle-stickyness', {force: true});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "fchat",
|
||||
"version": "1.11.0",
|
||||
"version": "1.12.0",
|
||||
"author": "The F-List Team and Mister Stallion (Esq.)",
|
||||
"description": "F-List.net Chat Client",
|
||||
"main": "main.js",
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
export enum Scoring {
|
||||
MATCH = 1,
|
||||
WEAK_MATCH = 0.5,
|
||||
NEUTRAL = 0,
|
||||
WEAK_MISMATCH = -0.5,
|
||||
MISMATCH = -1
|
||||
}
|
||||
|
||||
|
||||
export enum TagId {
|
||||
Age = 1,
|
||||
Orientation = 2,
|
||||
|
@ -11,10 +20,23 @@ export enum TagId {
|
|||
RelationshipStatus = 42,
|
||||
Species = 9,
|
||||
LanguagePreference = 49,
|
||||
PostLength = 24,
|
||||
|
||||
Kinks = 99999
|
||||
}
|
||||
|
||||
|
||||
export enum PostLengthPreference {
|
||||
NoPreference = 63,
|
||||
VeryShort_1_2 = 26,
|
||||
Short_2_4 = 27,
|
||||
SemiParagraph_4_7 = 28,
|
||||
Paragraph_7_10 = 60,
|
||||
StrongParagraph_10_14 = 61,
|
||||
MultiParagraph_14_25 = 62
|
||||
}
|
||||
|
||||
|
||||
export enum Gender {
|
||||
Male = 1,
|
||||
Female = 2,
|
||||
|
@ -103,6 +125,72 @@ export const furryPreferenceMapping = {
|
|||
};
|
||||
|
||||
|
||||
export const postLengthPreferenceMapping = {
|
||||
[PostLengthPreference.MultiParagraph_14_25]: 'multi-paragraph posts',
|
||||
[PostLengthPreference.StrongParagraph_10_14]: 'strong paragraph posts',
|
||||
[PostLengthPreference.Paragraph_7_10]: 'paragraph posts',
|
||||
[PostLengthPreference.SemiParagraph_4_7]: 'semi-paragraph posts',
|
||||
[PostLengthPreference.Short_2_4]: 'short posts',
|
||||
[PostLengthPreference.VeryShort_1_2]: 'very short posts'
|
||||
};
|
||||
|
||||
|
||||
export const postLengthPreferenceScoreMapping = {
|
||||
[PostLengthPreference.MultiParagraph_14_25]: {
|
||||
[PostLengthPreference.MultiParagraph_14_25]: Scoring.MATCH,
|
||||
[PostLengthPreference.StrongParagraph_10_14]: Scoring.MATCH,
|
||||
[PostLengthPreference.Paragraph_7_10]: Scoring.WEAK_MATCH,
|
||||
[PostLengthPreference.SemiParagraph_4_7]: Scoring.WEAK_MISMATCH,
|
||||
[PostLengthPreference.Short_2_4]: Scoring.MISMATCH,
|
||||
[PostLengthPreference.VeryShort_1_2]: Scoring.MISMATCH
|
||||
},
|
||||
|
||||
[PostLengthPreference.StrongParagraph_10_14]: {
|
||||
[PostLengthPreference.MultiParagraph_14_25]: Scoring.MATCH,
|
||||
[PostLengthPreference.StrongParagraph_10_14]: Scoring.MATCH,
|
||||
[PostLengthPreference.Paragraph_7_10]: Scoring.MATCH,
|
||||
[PostLengthPreference.SemiParagraph_4_7]: Scoring.WEAK_MISMATCH,
|
||||
[PostLengthPreference.Short_2_4]: Scoring.MISMATCH,
|
||||
[PostLengthPreference.VeryShort_1_2]: Scoring.MISMATCH
|
||||
},
|
||||
|
||||
[PostLengthPreference.Paragraph_7_10]: {
|
||||
[PostLengthPreference.MultiParagraph_14_25]: Scoring.WEAK_MATCH,
|
||||
[PostLengthPreference.StrongParagraph_10_14]: Scoring.MATCH,
|
||||
[PostLengthPreference.Paragraph_7_10]: Scoring.MATCH,
|
||||
[PostLengthPreference.SemiParagraph_4_7]: Scoring.WEAK_MATCH,
|
||||
[PostLengthPreference.Short_2_4]: Scoring.MISMATCH,
|
||||
[PostLengthPreference.VeryShort_1_2]: Scoring.MISMATCH
|
||||
},
|
||||
|
||||
[PostLengthPreference.SemiParagraph_4_7]: {
|
||||
[PostLengthPreference.MultiParagraph_14_25]: Scoring.MISMATCH,
|
||||
[PostLengthPreference.StrongParagraph_10_14]: Scoring.WEAK_MISMATCH,
|
||||
[PostLengthPreference.Paragraph_7_10]: Scoring.WEAK_MATCH,
|
||||
[PostLengthPreference.SemiParagraph_4_7]: Scoring.MATCH,
|
||||
[PostLengthPreference.Short_2_4]: Scoring.MATCH,
|
||||
[PostLengthPreference.VeryShort_1_2]: Scoring.WEAK_MATCH
|
||||
},
|
||||
|
||||
[PostLengthPreference.Short_2_4]: {
|
||||
[PostLengthPreference.MultiParagraph_14_25]: Scoring.MISMATCH,
|
||||
[PostLengthPreference.StrongParagraph_10_14]: Scoring.MISMATCH,
|
||||
[PostLengthPreference.Paragraph_7_10]: Scoring.WEAK_MISMATCH,
|
||||
[PostLengthPreference.SemiParagraph_4_7]: Scoring.WEAK_MATCH,
|
||||
[PostLengthPreference.Short_2_4]: Scoring.MATCH,
|
||||
[PostLengthPreference.VeryShort_1_2]: Scoring.MATCH
|
||||
},
|
||||
|
||||
[PostLengthPreference.VeryShort_1_2]: {
|
||||
[PostLengthPreference.MultiParagraph_14_25]: Scoring.MISMATCH,
|
||||
[PostLengthPreference.StrongParagraph_10_14]: Scoring.MISMATCH,
|
||||
[PostLengthPreference.Paragraph_7_10]: Scoring.MISMATCH,
|
||||
[PostLengthPreference.SemiParagraph_4_7]: Scoring.WEAK_MATCH,
|
||||
[PostLengthPreference.Short_2_4]: Scoring.MATCH,
|
||||
[PostLengthPreference.VeryShort_1_2]: Scoring.MATCH
|
||||
}
|
||||
};
|
||||
|
||||
export interface GenderKinkIdMap {
|
||||
[key: number]: Kink
|
||||
}
|
||||
|
@ -485,37 +573,37 @@ export interface SpeciesMappingCache {
|
|||
|
||||
|
||||
export const kinkMatchWeights = {
|
||||
logBase: 10,
|
||||
weakMismatchThreshold: 0.3,
|
||||
weakMatchThreshold: 0.3,
|
||||
unicornThreshold: 8.0
|
||||
// logBase: 10,
|
||||
weakMismatchThreshold: 16,
|
||||
weakMatchThreshold: 16,
|
||||
unicornThreshold: 9
|
||||
};
|
||||
|
||||
export const kinkMatchScoreMap = {
|
||||
favorite: {
|
||||
favorite: 0.5,
|
||||
yes: 0.25,
|
||||
maybe: -0.5,
|
||||
no: -2
|
||||
favorite: 1,
|
||||
yes: 0.5,
|
||||
maybe: -0.65,
|
||||
no: -1.5
|
||||
},
|
||||
|
||||
yes: {
|
||||
favorite: 0.3,
|
||||
yes: 0.2,
|
||||
maybe: -0.15,
|
||||
favorite: 0.5,
|
||||
yes: 0.5,
|
||||
maybe: -0.25,
|
||||
no: -0.5
|
||||
},
|
||||
|
||||
maybe: {
|
||||
favorite: -0.5,
|
||||
yes: -0.2,
|
||||
yes: -0.25,
|
||||
maybe: 0,
|
||||
no: 0
|
||||
},
|
||||
|
||||
no: {
|
||||
favorite: -2,
|
||||
yes: -0.5,
|
||||
favorite: -1.5,
|
||||
yes: -0.65,
|
||||
maybe: 0,
|
||||
no: 0
|
||||
}
|
||||
|
@ -571,6 +659,7 @@ export interface KinkBucketScore {
|
|||
score: number;
|
||||
count: number;
|
||||
weighted: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface MatchResultKinkScores {
|
||||
|
|
118
learn/matcher.ts
118
learn/matcher.ts
|
@ -3,22 +3,36 @@
|
|||
import * as _ from 'lodash';
|
||||
import { Character, CharacterInfotag, KinkChoice } from '../interfaces';
|
||||
import log from 'electron-log'; //tslint:disable-line:match-default-export-name
|
||||
|
||||
// tslint:disable-next-line ban-ts-ignore
|
||||
// @ts-ignore
|
||||
import anyAscii from 'any-ascii';
|
||||
|
||||
import {Store} from '../site/character_page/data_store';
|
||||
import { Store } from '../site/character_page/data_store';
|
||||
|
||||
import {
|
||||
BodyType, fchatGenderMap,
|
||||
BodyType,
|
||||
fchatGenderMap,
|
||||
FurryPreference,
|
||||
Gender, genderKinkMapping,
|
||||
Kink, KinkBucketScore, kinkComparisonExclusionGroups, kinkComparisonExclusions, kinkComparisonSwaps,
|
||||
kinkMapping, kinkMatchScoreMap, kinkMatchWeights,
|
||||
KinkPreference, likelyHuman, mammalSpecies, nonAnthroSpecies,
|
||||
Gender,
|
||||
genderKinkMapping,
|
||||
Kink,
|
||||
KinkBucketScore,
|
||||
kinkComparisonExclusionGroups,
|
||||
kinkComparisonExclusions,
|
||||
kinkComparisonSwaps,
|
||||
kinkMapping,
|
||||
kinkMatchScoreMap,
|
||||
kinkMatchWeights,
|
||||
KinkPreference,
|
||||
likelyHuman,
|
||||
mammalSpecies,
|
||||
nonAnthroSpecies,
|
||||
Orientation,
|
||||
Species, SpeciesMap, speciesMapping, SpeciesMappingCache,
|
||||
PostLengthPreference, postLengthPreferenceMapping, postLengthPreferenceScoreMapping, Scoring,
|
||||
Species,
|
||||
SpeciesMap,
|
||||
speciesMapping,
|
||||
SpeciesMappingCache,
|
||||
speciesNames,
|
||||
SubDomRole,
|
||||
TagId
|
||||
|
@ -68,13 +82,6 @@ export interface MatchResult {
|
|||
theirAnalysis: CharacterAnalysis;
|
||||
}
|
||||
|
||||
export enum Scoring {
|
||||
MATCH = 1,
|
||||
WEAK_MATCH = 0.5,
|
||||
NEUTRAL = 0,
|
||||
WEAK_MISMATCH = -0.5,
|
||||
MISMATCH = -1
|
||||
}
|
||||
|
||||
export interface ScoreClassMap {
|
||||
[key: number]: string;
|
||||
|
@ -141,6 +148,7 @@ export class CharacterAnalysis {
|
|||
readonly furryPreference: FurryPreference | null;
|
||||
readonly age: number | null;
|
||||
readonly subDomRole: SubDomRole | null;
|
||||
readonly postLengthPreference: PostLengthPreference | null;
|
||||
|
||||
readonly isAnthro: boolean | null;
|
||||
readonly isHuman: boolean | null;
|
||||
|
@ -154,6 +162,7 @@ export class CharacterAnalysis {
|
|||
this.species = Matcher.species(c);
|
||||
this.furryPreference = Matcher.getTagValueList(TagId.FurryPreference, c);
|
||||
this.subDomRole = Matcher.getTagValueList(TagId.SubDomRole, c);
|
||||
this.postLengthPreference = Matcher.getTagValueList(TagId.PostLength, c);
|
||||
|
||||
const ageTag = Matcher.getTagValue(TagId.Age, c);
|
||||
|
||||
|
@ -391,7 +400,8 @@ export class Matcher {
|
|||
[TagId.FurryPreference]: this.resolveFurryPairingsScore(),
|
||||
[TagId.Species]: this.resolveSpeciesScore(),
|
||||
[TagId.SubDomRole]: this.resolveSubDomScore(),
|
||||
[TagId.Kinks]: this.resolveKinkScore(pronoun)
|
||||
[TagId.Kinks]: this.resolveKinkScore(pronoun),
|
||||
[TagId.PostLength]: this.resolvePostLengthScore()
|
||||
},
|
||||
|
||||
info: {
|
||||
|
@ -487,6 +497,24 @@ export class Matcher {
|
|||
return new Score(Scoring.NEUTRAL);
|
||||
}
|
||||
|
||||
private resolvePostLengthScore(): Score {
|
||||
const yourLength = this.yourAnalysis.postLengthPreference;
|
||||
const theirLength = this.theirAnalysis.postLengthPreference;
|
||||
|
||||
if (
|
||||
(!yourLength)
|
||||
|| (!theirLength)
|
||||
|| (yourLength === PostLengthPreference.NoPreference)
|
||||
|| (theirLength === PostLengthPreference.NoPreference)
|
||||
) {
|
||||
return new Score(Scoring.NEUTRAL);
|
||||
}
|
||||
|
||||
const score = postLengthPreferenceScoreMapping[yourLength][theirLength];
|
||||
|
||||
return this.formatScoring(score, postLengthPreferenceMapping[theirLength]);
|
||||
}
|
||||
|
||||
private resolveSpeciesScore(): Score {
|
||||
const you = this.you;
|
||||
const theirAnalysis = this.theirAnalysis;
|
||||
|
@ -568,23 +596,32 @@ export class Matcher {
|
|||
|
||||
|
||||
private resolveKinkScore(pronoun: string): Score {
|
||||
const kinkScore = this.resolveKinkBucketScore('all');
|
||||
// const kinkScore = this.resolveKinkBucketScore('all');
|
||||
|
||||
log.debug('report.score.kink', this.them.name, this.you.name, kinkScore.count, kinkScore.score, kinkScore.weighted);
|
||||
const scores = {
|
||||
favorite: this.resolveKinkBucketScore('favorite'),
|
||||
yes: this.resolveKinkBucketScore('yes'),
|
||||
maybe: this.resolveKinkBucketScore('maybe'),
|
||||
no: this.resolveKinkBucketScore('no')
|
||||
};
|
||||
|
||||
if (kinkScore.weighted === 0) {
|
||||
const weighted = scores.favorite.weighted + scores.yes.weighted + scores.maybe.weighted + scores.no.weighted;
|
||||
|
||||
log.debug('report.score.kink', this.them.name, this.you.name, scores, weighted);
|
||||
|
||||
if (weighted === 0) {
|
||||
return new Score(Scoring.NEUTRAL);
|
||||
}
|
||||
|
||||
if (kinkScore.weighted < 0) {
|
||||
if (Math.abs(kinkScore.weighted) < kinkMatchWeights.weakMismatchThreshold) {
|
||||
if (weighted < 0) {
|
||||
if (Math.abs(weighted) < kinkMatchWeights.weakMismatchThreshold) {
|
||||
return new Score(Scoring.WEAK_MISMATCH, `Hesitant about ${pronoun} <span>kinks</span>`);
|
||||
}
|
||||
|
||||
return new Score(Scoring.MISMATCH, `Dislikes ${pronoun} <span>kinks</span>`);
|
||||
}
|
||||
|
||||
if (Math.abs(kinkScore.weighted) < kinkMatchWeights.weakMatchThreshold) {
|
||||
if (Math.abs(weighted) < kinkMatchWeights.weakMatchThreshold) {
|
||||
return new Score(Scoring.WEAK_MATCH, `Likes ${pronoun} <span>kinks</span>`);
|
||||
}
|
||||
|
||||
|
@ -793,42 +830,49 @@ export class Matcher {
|
|||
(accum, yourKinkValue: any, yourKinkId: any) => {
|
||||
const theirKinkId = (yourKinkId in kinkComparisonSwaps) ? kinkComparisonSwaps[yourKinkId] : yourKinkId;
|
||||
|
||||
const isExcluded = (yourKinkId in kinkComparisonExclusions)
|
||||
|| ((Store.shared.kinks[yourKinkId]) && (Store.shared.kinks[yourKinkId].kink_group in kinkComparisonExclusionGroups));
|
||||
|
||||
const isBucketMatch = (yourKinkValue === bucket)
|
||||
|| (bucket === 'all')
|
||||
|| ((bucket === 'negative') && ((yourKinkValue === 'no') || (yourKinkValue === 'maybe')))
|
||||
|| ((bucket === 'positive') && ((yourKinkValue === 'favorite') || (yourKinkValue === 'yes')));
|
||||
|
||||
if ((isBucketMatch) && (!isExcluded)) {
|
||||
accum.total += 1;
|
||||
}
|
||||
|
||||
if (
|
||||
(!(theirKinkId in theirKinks))
|
||||
|| (yourKinkId in kinkComparisonExclusions)
|
||||
|| ((Store.shared.kinks[yourKinkId]) && (Store.shared.kinks[yourKinkId].kink_group in kinkComparisonExclusionGroups))
|
||||
|| (isExcluded)
|
||||
) {
|
||||
return accum;
|
||||
}
|
||||
|
||||
const theirKinkValue = theirKinks[theirKinkId] as any;
|
||||
|
||||
if (
|
||||
(yourKinkValue === bucket)
|
||||
|| (bucket === 'all')
|
||||
|| ((bucket === 'negative') && ((yourKinkValue === 'no') || (yourKinkValue === 'maybe')))
|
||||
|| ((bucket === 'positive') && ((yourKinkValue === 'favorite') || (yourKinkValue === 'yes')))
|
||||
) {
|
||||
if (isBucketMatch) {
|
||||
return {
|
||||
score: accum.score + this.getKinkMatchScore(yourKinkValue, theirKinkValue),
|
||||
count: accum.count + 1
|
||||
count: accum.count + 1,
|
||||
total: accum.total
|
||||
};
|
||||
}
|
||||
|
||||
// missed += 1;
|
||||
return accum;
|
||||
},
|
||||
{ score: 0, count: 0 }
|
||||
{ score: 0, count: 0, total: 0 }
|
||||
);
|
||||
|
||||
// const yourBucketCounts = this.countKinksByBucket(yourKinks);
|
||||
// const theirBucketCounts = this.countKinksByBucket(theirKinks);
|
||||
|
||||
result.weighted = (result.count === 0)
|
||||
result.weighted = ((result.count === 0) || (Math.abs(result.score) < 1))
|
||||
? 0
|
||||
: (
|
||||
(Math.log(result.count) / Math.log(kinkMatchWeights.logBase)) // log 8 base
|
||||
* (result.score / result.count)
|
||||
Math.log(result.total) * Math.log(Math.abs(result.score)) * Math.sign(result.score)
|
||||
// (Math.log(result.count) / Math.log(kinkMatchWeights.logBase)) // log 8 base
|
||||
// * (result.score / result.count)
|
||||
);
|
||||
|
||||
return result;
|
||||
|
@ -873,7 +917,7 @@ export class Matcher {
|
|||
|
||||
|
||||
private getKinkMatchScore(aValue: string, bValue: string): number {
|
||||
return _.get(kinkMatchScoreMap, `${aValue}.${bValue}`, 0);
|
||||
return _.get(kinkMatchScoreMap, `${aValue}.${bValue}`, 0) * 7; // forces range above 1.0
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,9 +3,10 @@ import * as _ from 'lodash';
|
|||
import core from '../chat/core';
|
||||
import {Character as ComplexCharacter, CharacterGroup, Guestbook} from '../site/character_page/interfaces';
|
||||
import { AsyncCache } from './async-cache';
|
||||
import { Matcher, MatchReport, Scoring } from './matcher';
|
||||
import { Matcher, MatchReport } from './matcher';
|
||||
import { PermanentIndexedStore } from './store/types';
|
||||
import { CharacterImage, SimpleCharacter } from '../interfaces';
|
||||
import { Scoring } from './matcher-types';
|
||||
|
||||
|
||||
export interface MetaRecord {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "f-list-rising",
|
||||
"version": "1.11.0",
|
||||
"version": "1.12.0",
|
||||
"author": "The F-List Team and and Mister Stallion (Esq.)",
|
||||
"description": "A heavily modded F-Chat 3.0 client for F-List",
|
||||
"license": "MIT",
|
||||
|
@ -52,9 +52,9 @@
|
|||
"webpack": "^5.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cliqz/adblocker-electron": "^1.20.0",
|
||||
"@cliqz/adblocker-electron": "^1.20.4",
|
||||
"jquery": "^3.6.0",
|
||||
"keytar": "^7.4.0",
|
||||
"keytar": "^7.5.0",
|
||||
"node-fetch": "^2.6.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
}
|
||||
|
||||
theirInterestIsRelevant(id: number): boolean {
|
||||
return ((id === TagId.FurryPreference) || (id === TagId.Orientation) || (id === TagId.SubDomRole));
|
||||
return ((id === TagId.FurryPreference) || (id === TagId.Orientation) || (id === TagId.SubDomRole) || (id === TagId.PostLength));
|
||||
}
|
||||
|
||||
yourInterestIsRelevant(id: number): boolean {
|
||||
|
|
|
@ -37,9 +37,9 @@
|
|||
import * as _ from 'lodash';
|
||||
import Vue from 'vue';
|
||||
import * as Utils from '../utils';
|
||||
import { Matcher, MatchReport, MatchResult, Score, Scoring } from '../../learn/matcher';
|
||||
import { Matcher, MatchReport, MatchResult, Score } from '../../learn/matcher';
|
||||
import core from '../../chat/core';
|
||||
import { TagId } from '../../learn/matcher-types';
|
||||
import { Scoring, TagId } from '../../learn/matcher-types';
|
||||
|
||||
export interface CssClassMap {
|
||||
[key: string]: boolean;
|
||||
|
|
60
yarn.lock
60
yarn.lock
|
@ -23,41 +23,41 @@
|
|||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@cliqz/adblocker-content@^1.20.3":
|
||||
version "1.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@cliqz/adblocker-content/-/adblocker-content-1.20.3.tgz#198c8719cd62ef3c67a5c98e7a54336b7812ed86"
|
||||
integrity sha512-aCBTiIiNgVbmDIQyUcsn0j3n+umvs0DuVlL6dccPE3qfeFxT4whUvMwjxUS2/dIBfJK9A1LywmvVke2eSPw9wg==
|
||||
"@cliqz/adblocker-content@^1.20.4":
|
||||
version "1.20.4"
|
||||
resolved "https://registry.yarnpkg.com/@cliqz/adblocker-content/-/adblocker-content-1.20.4.tgz#68c0c628acd6da49bb5a6ad9ee0cb540a8d50acd"
|
||||
integrity sha512-Cp6M6MERCsLwklX6lAmrgOxom0pr4DjxmUGLcmM9MDACOIzk/m7ya1e82bXzEWAU1Jni2Bp91xUUWxg+DLWJgQ==
|
||||
dependencies:
|
||||
"@cliqz/adblocker-extended-selectors" "^1.20.3"
|
||||
"@cliqz/adblocker-extended-selectors" "^1.20.4"
|
||||
|
||||
"@cliqz/adblocker-electron-preload@^1.20.3":
|
||||
version "1.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@cliqz/adblocker-electron-preload/-/adblocker-electron-preload-1.20.3.tgz#17dff446ad742cb6e68a4572e7a75cff1fa33f95"
|
||||
integrity sha512-fWAFEGj+F0VOUKZd2FqWLuguXmGzkRQz5wTCqasvndX4HSe0P8Pd2666pWK9RJW1dLJE7U61mQfTbYqlUFVTMA==
|
||||
"@cliqz/adblocker-electron-preload@^1.20.4":
|
||||
version "1.20.4"
|
||||
resolved "https://registry.yarnpkg.com/@cliqz/adblocker-electron-preload/-/adblocker-electron-preload-1.20.4.tgz#b7d6606dfc24e7b3f80109cc6820bd203faaf26e"
|
||||
integrity sha512-tIEgFJJhEDTYrSUzAL+wbw+BBVwCtuFtckA/scka990DGlXsEmkJ7HxNXvUPwhOQiV4YUwN5bsqxCDA8VDTZNw==
|
||||
dependencies:
|
||||
"@cliqz/adblocker-content" "^1.20.3"
|
||||
"@cliqz/adblocker-content" "^1.20.4"
|
||||
|
||||
"@cliqz/adblocker-electron@^1.20.0":
|
||||
version "1.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@cliqz/adblocker-electron/-/adblocker-electron-1.20.3.tgz#f2b4bf5dddf90f64251c46f89238526dc0037384"
|
||||
integrity sha512-ZcEl3W7R/aoUA0IPIMtvdn7gVE6O9+rDQ9OllIH/s/gVeElXZsgPEtpPMSuoJWbi9d2mlr8yo3UFvkV3u7c4gw==
|
||||
"@cliqz/adblocker-electron@^1.20.4":
|
||||
version "1.20.4"
|
||||
resolved "https://registry.yarnpkg.com/@cliqz/adblocker-electron/-/adblocker-electron-1.20.4.tgz#6d7de52cff013ef3cd0f4a7850ebfc31f6240a46"
|
||||
integrity sha512-HaHexPnJL1BBvloXuqmSh8WtpPKYHyZ+o6f+9SciySN4dJAX9BIGTk9D/V6eJWLmy6+wY7/Bpcn2Q4nrYXsqBw==
|
||||
dependencies:
|
||||
"@cliqz/adblocker" "^1.20.3"
|
||||
"@cliqz/adblocker-electron-preload" "^1.20.3"
|
||||
"@cliqz/adblocker" "^1.20.4"
|
||||
"@cliqz/adblocker-electron-preload" "^1.20.4"
|
||||
tldts-experimental "^5.6.21"
|
||||
|
||||
"@cliqz/adblocker-extended-selectors@^1.20.3":
|
||||
version "1.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@cliqz/adblocker-extended-selectors/-/adblocker-extended-selectors-1.20.3.tgz#a817915948ec4e64c8b878a80a71d911ea0412c8"
|
||||
integrity sha512-Xsrqg4qgpNVx80UJrAz/nS8jcbgCTIGvir0MrjoXrw0GheqRxsgE540XXP9JA7QlifLNVEOO44DpHvhUmISkQw==
|
||||
"@cliqz/adblocker-extended-selectors@^1.20.4":
|
||||
version "1.20.4"
|
||||
resolved "https://registry.yarnpkg.com/@cliqz/adblocker-extended-selectors/-/adblocker-extended-selectors-1.20.4.tgz#6f5ab8251a0d40cacf3703f5621025e0d85d6348"
|
||||
integrity sha512-VBP8iv1IdYpwQ0hbbeiXCSW7ppzK05dbPM4DyeCb54mB0CjWj/pMQwEvjMZKLWTkEyPd26oMqnxNQz1UgGaZag==
|
||||
|
||||
"@cliqz/adblocker@^1.20.3":
|
||||
version "1.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@cliqz/adblocker/-/adblocker-1.20.3.tgz#4e8d03ed03c476f7b4388d25f910b1b9e0b15cc9"
|
||||
integrity sha512-Dqj8fJ399kFsFQ53uW0ajA5jH5VJ5ppawOjtoV2s+7NILj1ydvw40jTrr3l/ObMvxaAGaDUj2Euo4beg3/EtRQ==
|
||||
"@cliqz/adblocker@^1.20.4":
|
||||
version "1.20.4"
|
||||
resolved "https://registry.yarnpkg.com/@cliqz/adblocker/-/adblocker-1.20.4.tgz#63f75456b6d63f66dc73b9ac2971ed073bf26722"
|
||||
integrity sha512-ylwc4fScwgDjh9mKAvBQ+oCNyZWncrPakU17KbMtq+l82LkzJ0ND0wififpeq+nI9JBiQosW+eus5R08THpwCQ==
|
||||
dependencies:
|
||||
"@cliqz/adblocker-content" "^1.20.3"
|
||||
"@cliqz/adblocker-extended-selectors" "^1.20.3"
|
||||
"@cliqz/adblocker-content" "^1.20.4"
|
||||
"@cliqz/adblocker-extended-selectors" "^1.20.4"
|
||||
"@remusao/guess-url-type" "^1.1.2"
|
||||
"@remusao/small" "^1.1.2"
|
||||
"@remusao/smaz" "^1.7.1"
|
||||
|
@ -4271,10 +4271,10 @@ junk@^3.1.0:
|
|||
resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1"
|
||||
integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==
|
||||
|
||||
keytar@^7.4.0:
|
||||
version "7.4.0"
|
||||
resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.4.0.tgz#0a508d64850ca05aa3ba4127818037d13ca3219f"
|
||||
integrity sha512-nELmc35YjSE4ZNSFaID/743CgDt/MdV4JLX7rRewAh9mKvU72RtF3uJMY0MdMpwdDYZhmD8FSdRCD1J97lEyVg==
|
||||
keytar@^7.5.0:
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.6.0.tgz#498e796443cb543d31722099443f29d7b5c44100"
|
||||
integrity sha512-H3cvrTzWb11+iv0NOAnoNAPgEapVZnYLVHZQyxmh7jdmVfR/c0jNNFEZ6AI38W/4DeTGTaY66ZX4Z1SbfKPvCQ==
|
||||
dependencies:
|
||||
node-addon-api "^3.0.0"
|
||||
prebuild-install "^6.0.0"
|
||||
|
|
Loading…
Reference in New Issue