This commit is contained in:
Mr. Stallion 2024-01-28 17:21:09 -08:00
parent 2a0a0d3761
commit 1a2cc1e6f0
10 changed files with 129 additions and 22 deletions

View File

@ -1,5 +1,11 @@
# Changelog
## Canary
* Added high-quality portrait check to Profile Helper
* Added option for disabling high-quality portraits
* Added cleaner `[quote][/quote]` style for profiles
* Fixed Redgifs previews (again)
## 1.26.0
* High-quality portraits
* Override the default 100x100px portrait with a high-resolution image
@ -18,7 +24,7 @@
* High-quality portraits are only visible to other F-Chat Rising users; users on other clients will see your regular portrait.
* If your image is not a square, [you're gonna have a bad time](https://www.youtube.com/watch?v=6Ls5j5iz2eA).
* [YiffBot 4000](https://www.f-list.net/c/YiffBot%204000) integration
* Fix "select/unselect all" behavior in Post Ads (credit: [@FatCatClient](https://github.com/FatCatClient))
* Fixed "select/unselect all" behavior in Post Ads (credit: [@FatCatClient](https://github.com/FatCatClient))
* Extended emoji support (credit: [@FatCatClient](https://github.com/FatCatClient))
## 1.25.1

View File

@ -151,8 +151,8 @@ export default class EIconSelector extends CustomDialog {
case 'symbols':
return ['loveslove', 'pimpdcash', 'pls stop', 'paw2', 'gender-female', 'gender-male', 'gendershemale', 'gender-cuntboy', 'gender-mherm',
'gender-transgender', 'usflag', 'europeflag', 'lgbt', 'transflag', 'sunnyuhsuperlove', 'discovered', 'thbun',
'goldcoin1', 'star', 'full moon', 'sunshine', 'pinetree', 'carrots1', 'smashletter', 'chemicalscience', 'ghostbuster',
'gender-transgender', 'usflag', 'europeflag', 'lgbt', 'transflag', 'sunnyuhsuperlove', 'discovered',
'goldcoin1', 'star', 'full moon', 'sunshine', 'pinetree', 'carrots1', 'smashletter', 'ghostbuster',
'cuckquean', 'goldendicegmgolddicegif', 'pentagramo', 'sexsymbol', 'idnd1', 'instagram', 'twitterlogo', 'snapchaticon',
'tiktok', 'twitchlogo', 'discord', 'uber', 'google', 'nvidia', 'playstation',
'suitclubs', 'suitdiamonds', 'suithearts', 'suitspades', 'chainscuffs',
@ -164,11 +164,11 @@ export default class EIconSelector extends CustomDialog {
case 'bubbles':
return ['takemetohornyjail', 'notcashmoney', 'lickme', 'iacs', 'imahugeslut', 'fuckyouasshole', 'bubblecute', 'pat my head',
'chorse', 'knotslutbubble', 'toofuckinghot', 'pbmr', 'imabimbo', 'dicefuck', 'ciaig', 'horseslut', 'fatdick', 'tomboypussy',
'breakthesubs', 'fuckingnya', 'iltclion', 'suckfuckobey', 'shemale', 'breedmaster', 'imastepfordwife', 'prier ahegao',
'breakthesubs', 'fuckingnya', 'iltclion', 'suckfuckobey', 'shemale', 'breedmaster', 'imastepfordwife', 'ahegaoalert2',
'buttslutbb', 'notgayoranything', 'onlyfans', 'horsecockneed', 'crimes', 'breed143', 'nagagross', 'willrim', 'muskslut',
'4lewdbubble', 'shimathatlewd', 'hypnosiss', 'imahypnoslut', 'sheepsass2', 'imahugeslut', 'notahealslut', 'ratedmilf',
'ratedstud', 'ratedslut', '5lewdbubble', 'xarcuminme', 'xarcumonme', 'choke me', 'iamgoingtopunchyou', 'snapmychoker',
'rude1', 'fuckbun', 'iamindanger', 'fuckingelves', 'sluttery', 'helpicantstopsuckingcocks', 'talkpooltoy', 'thatskindahot', 'ygod',
'rude1', 'fuckbun', 'iamindanger', 'elves', 'sluttery', 'helpicantstopsuckingcocks', 'talkpooltoy', 'thatskindahot', 'ygod',
'simpbait', 'eyesuphere', 'fuckpiggy', 'peggable2', 'sydeanothere', 'nothingcan', 'pawslut', 'stupidboys', 'corpsestare-',
'dinnersex', 'plappening', 'fallout-standby', 'inbagg', 'request denied', 'goodboy0', 'goodending', 'milky2', 'howbadcanibe',
'gwanna', 'spitinmouth', 'bathwater'];
@ -178,15 +178,15 @@ export default class EIconSelector extends CustomDialog {
'rorobutt2', 'fingerlick', 'lapgrind', 'jackthighs', 'a condom', 'wolf abs', 'musclefuck2', 'verobutt3', 'bumsqueeze',
'realahegao4', 'influencerhater', 'assfucker', 'gagged2', 'ballsack3', 'fingerblast3', 'sloppy01', 'sybian',
'floppyhorsecock', 'blackshem1', 'fingersucc', 'vullylick', 'fingersucc', 'cmontakeit', 'jessi flash', 'poju-butt',
'cheegrope2', 'patr1', 'ahega01 2', 'handjob1nuke', 'harmanfingers', 'hermione1', '2buttw1', 'dropsqueeze',
'cheegrope2', 'patr1', 'ahega01 2', 'handjob1nuke', 'harmanfingers', '2buttw1', 'dropsqueeze',
'lixlove', 'bbctitjob6', 'appreciativetease', 'bimbowhisper', 'subj3', 'salivashare', 'ballsworship3', 'wolfsknot2', 'gaykiss',
'slurpkiss', 'absbulge', 'cockiss', 'horsedick11', 'knot1', 'g4ebulge', 'blackadamrough', 'knotdog', 'flaunt', 'cummiefj', 'lovetosuck',
'slurpkiss', 'absbulge', 'cockiss', 'horsedick11', 'knotknotknot', 'g4ebulge', 'blackadamrough', 'knotdog', 'flaunt', 'cummiefj', 'lovetosuck',
'worship', 'hopelessly in love', 'knotts', 'cockloveeee', 'donglove', 'knotjob2', 'cummz', 'every drop', 'edgyoops',
'orccummies2', 'oralcreampie100px', 'horseoral9a', 'swallowit', 'realahegao4', 'gayicon2', 'slut4', 'hossspurties2', 'cumringgag',
'jillbimbogiffell2'];
case 'memes':
return ['guncock', 'michaelguns', 'watchbadass', 'gonnabang', 'flirting101', 'monkeymeme', 'monkeymeme2', 'horsenoises',
return ['guncock', 'michaelguns', 'watchbadass', 'gonnabang', 'flirting101', 'monkeymeme', 'monkeymeme2', 'loudnoises',
'nyancat', 'gayb', 'fortasshole', 'dickletsign', 'sausageface', 'siren0', 'apologize to god', 'jabbalick', 'zeldawink',
'whatislove', 'surprisemothafucka', 'females', 'thanksihateit', 'hell is this', 'confused travolta', 'no words', 'coffindance',
'homelander', 'thatsapenis', 'pennyhee', 'kermitbusiness', 'goodbye', 'rickle', 'shiamagic', 'oag', ];

View File

@ -52,6 +52,7 @@
</template>
</div>
</div>
<div class="search-yiffbot-suggestion" v-if="isYiffBot4000Online()" @click.prevent="showYiffBot4000()"><div class="btn">No luck? Try AI play with <span>YiffBot 4000</span></div></div>
</modal>
</template>
@ -94,7 +95,6 @@
profile: CharacterCacheRecord | null;
}
function sort(resultX: SearchResult, resultY: SearchResult): number {
const x = resultX.character;
const y = resultY.character;
@ -185,6 +185,29 @@
// tslint:disable-next-line no-any
scoreWatcher: ((event: any) => void) | null = null;
isYiffBot4000Online(): boolean {
return core.characters.get('YiffBot 4000').status !== 'offline';
}
showYiffBot4000(): void {
const character = core.characters.get('YiffBot 4000');
if (character.status === 'offline') {
return;
}
const conversation = core.conversations.getPrivate(character);
conversation.show();
this.hide();
const last = _.last(conversation.messages);
if (!last || last.time.getTime() < Date.now() - 1000 * 60 * 30) {
conversation.enteredText = 'Hello!';
conversation.send();
}
}
@Hook('created')
async created(): Promise<void> {
@ -695,5 +718,24 @@
.search-spinner {
// float: right;
}
.search-yiffbot-suggestion .btn {
padding-left: 5px;
padding-right: 5px;
margin-top: 1em;
margin-bottom: 0;
padding-top: 0;
padding-bottom: 0;
background-color: var(--secondary);
&:hover {
background-color: var(--blue);
}
span {
color: var(--yellow);
font-weight: bold;
}
}
}
</style>

View File

@ -212,6 +212,13 @@
Show character portrait with each message
</label>
</div>
<div class="form-group">
<label class="control-label" for="risingShowHighQualityPortraits">
<input type="checkbox" id="risingShowHighQualityPortraits" v-model="risingShowHighQualityPortraits"/>
Show high-quality portraits
</label>
</div>
</div>
<div v-show="selectedTab === '3'">
@ -383,6 +390,7 @@
risingShowPortraitNearInput!: boolean;
risingShowPortraitInMessage!: boolean;
risingShowHighQualityPortraits!: boolean;
risingFilter!: SmartFilterSettings = {} as any;
@ -427,6 +435,7 @@
this.risingColorblindMode = settings.risingColorblindMode;
this.risingShowPortraitNearInput = settings.risingShowPortraitNearInput;
this.risingShowPortraitInMessage = settings.risingShowPortraitInMessage;
this.risingShowHighQualityPortraits = settings.risingShowHighQualityPortraits;
this.risingFilter = settings.risingFilter;
}
@ -490,6 +499,7 @@
risingShowUnreadOfflineCount: this.risingShowUnreadOfflineCount,
risingShowPortraitNearInput: this.risingShowPortraitNearInput,
risingShowPortraitInMessage: this.risingShowPortraitInMessage,
risingShowHighQualityPortraits: this.risingShowHighQualityPortraits,
risingColorblindMode: this.risingColorblindMode,
risingFilter: {

View File

@ -63,6 +63,7 @@ export class Settings implements ISettings {
risingColorblindMode = false;
risingShowPortraitNearInput = true;
risingShowPortraitInMessage = true;
risingShowHighQualityPortraits = true;
risingFilter = {
hideAds: false,

View File

@ -237,6 +237,7 @@ export namespace Settings {
readonly risingColorblindMode: boolean;
readonly risingShowPortraitNearInput: boolean;
readonly risingShowPortraitInMessage: boolean;
readonly risingShowHighQualityPortraits: boolean;
readonly risingFilter: SmartFilterSettings;
}

View File

@ -5,6 +5,7 @@ import path from 'path';
import fs from 'fs';
import * as _ from 'lodash';
import * as electron from 'electron';
import { NetworkFilter } from '@cliqz/adblocker';
export class BlockerIntegration {
protected static readonly adBlockerLists = [
@ -53,13 +54,17 @@ export class BlockerIntegration {
log.debug('adblock.session.created');
blocker.update({
newNetworkFilters: [
NetworkFilter.parse('@@||redgifs.com')!,
]
});
blocker.enableBlockingInSession(session);
// blocker.enableBlockingInSession(electron.session.defaultSession);
log.debug('adblock.enabled');
BlockerIntegration.configureBlocker(blocker, session);
// BlockerIntegration.configureBlocker(blocker, electron.session.defaultSession);
log.debug('adblock.session.attached');

View File

@ -72,7 +72,7 @@ export class ProfileCache extends AsyncCache<CharacterCacheRecord> {
}
async get(name: string, skipStore: boolean = false, fromChannel?: string): Promise<CharacterCacheRecord | null> {
async get(name: string, skipStore: boolean = false, _fromChannel?: string): Promise<CharacterCacheRecord | null> {
const key = AsyncCache.nameKey(name);
if (key in this.cache) {
@ -149,7 +149,7 @@ export class ProfileCache extends AsyncCache<CharacterCacheRecord> {
}
}
isSafeImageURL(url: string): boolean {
static isSafeRisingPortraitURL(url: string): boolean {
if (url.match(/^https?:\/\/static\.f-list\.net\//i)) {
return true;
}
@ -177,14 +177,26 @@ export class ProfileCache extends AsyncCache<CharacterCacheRecord> {
return false;
}
updateOverrides(c: ComplexCharacter): void {
const match = c.character.description.match(/\[url=(.*?)]\s*?Rising\s*?Portrait\s*?\[\/url]/i);
static detectRisingPortraitURL(description: string): string | null {
if (!core.state.settings.risingShowHighQualityPortraits) {
return null;
}
const match = description.match(/\[url=(.*?)]\s*?Rising\s*?Portrait\s*?\[\/url]/i);
if (match && match[1]) {
const avatarUrl = match[1].trim();
return match[1].trim();
}
if (!this.isSafeImageURL(avatarUrl)) {
log.info('portrait.hq.invalid.domain', { name: c.character.name, url: avatarUrl });
return null;
}
updateOverrides(c: ComplexCharacter): void {
const avatarUrl = ProfileCache.detectRisingPortraitURL(c.character.description);
if (avatarUrl) {
if (!ProfileCache.isSafeRisingPortraitURL(avatarUrl)) {
log.info('portrait.hq.invalid.domain', { name, url: avatarUrl });
return;
}
@ -199,7 +211,6 @@ export class ProfileCache extends AsyncCache<CharacterCacheRecord> {
}
}
async register(c: ComplexCharacter, skipStore: boolean = false): Promise<CharacterCacheRecord> {
const k = AsyncCache.nameKey(c.character.name);
const match = ProfileCache.match(c);

View File

@ -4,6 +4,7 @@ import Axios from 'axios';
import { CharacterAnalysis, Matcher } from '../matcher';
import { FurryPreference, Kink, mammalSpecies, Species } from '../matcher-types';
import { characterImage } from '../../chat/common';
import { ProfileCache } from '../profile-cache';
export enum ProfileRecommendationLevel {
INFO = 'info',
@ -39,6 +40,7 @@ export class ProfileRecommendationAnalyzer {
this.recommendations = [];
await this.checkPortrait();
await this.checkHqPortrait();
this.checkMissingProperties();
this.checkSpeciesPreferences();
@ -53,15 +55,25 @@ export class ProfileRecommendationAnalyzer {
}
protected async checkPortrait(): Promise<void> {
const profileUrl = characterImage(this.profile.character.name);
const portraitUrl = characterImage(this.profile.character.name);
const result = await Axios.head(profileUrl);
const result = await Axios.head(portraitUrl);
if (_.trim(result.headers['etag'] || '', '"').trim().toLowerCase() === '639d154d-16c3') {
this.add(`ADD_AVATAR`, ProfileRecommendationLevel.CRITICAL, 'Add an avatar portrait', 'Profiles with an avatar portrait stand out in chats.', 'https://wiki.f-list.net/Guide:_Character_Profiles#Avatar');
}
}
protected async checkHqPortrait(): Promise<void> {
const profileUrl = ProfileCache.detectRisingPortraitURL(this.profile.character.description);
if (!profileUrl) {
this.add(`ADD_HQ_AVATAR`, ProfileRecommendationLevel.CRITICAL, 'Add a high-quality portrait', 'Profiles with a high-quality portraits stand out in chats with other F-Chat Rising players.', 'https://github.com/hearmeneigh/fchat-rising/wiki/High%E2%80%90Quality-Portraits');
} else if (!ProfileCache.isSafeRisingPortraitURL(profileUrl)) {
this.add(`ADD_HQ_AVATAR_SAFE_DOMAIN`, ProfileRecommendationLevel.CRITICAL, 'Unsupported high-quality portrait URL', 'High-quality portraits can only point to f-list.net, freeimages.host, e621.net, iili.io, imgur.com, or redgifs.com domains.', 'https://github.com/hearmeneigh/fchat-rising/wiki/High%E2%80%90Quality-Portraits');
}
}
protected checkImages(): void {
if (!this.profile.character.image_count) {
this.add(`ADD_IMAGE`, ProfileRecommendationLevel.CRITICAL, 'Add a profile image', 'Profiles with images are more attractive to other players.', 'https://wiki.f-list.net/Guide:_Character_Profiles#Images');

View File

@ -39,7 +39,7 @@
<div role="tabpanel" v-show="tab === '0'" id="overview">
<match-report :characterMatch="characterMatch" v-if="shouldShowMatch()"></match-report>
<div style="margin-bottom:10px">
<div style="margin-bottom:10px" class="character-description">
<bbcode :text="character.character.description"></bbcode>
</div>
@ -934,4 +934,23 @@
background: var(--headerBackgroundMaskColor) !important;
}
.character-description .bbcode {
white-space: pre-line !important;
blockquote {
margin: 0;
background-color: var(--characterImageWrapperBg);
padding: 1em;
border-radius: 3px;
.quoteHeader {
border-bottom: 1px solid;
text-transform: uppercase;
font-weight: bold;
font-size: 80%;
opacity: 0.7;
}
}
}
</style>