Search history
This commit is contained in:
		
							parent
							
								
									79cfb2b938
								
							
						
					
					
						commit
						a95d483eb6
					
				| @ -15,8 +15,13 @@ | |||||||
|                 Searching for <span>{{searchString}}</span> |                 Searching for <span>{{searchString}}</span> | ||||||
|             </div> |             </div> | ||||||
| 
 | 
 | ||||||
|  |             <div class="btn-group"> | ||||||
|  |                 <button class="btn btn-outline-secondary" @click.prevent="showHistory()">History</button> | ||||||
|                 <button class="btn btn-outline-secondary" @click.prevent="reset()">Reset</button> |                 <button class="btn btn-outline-secondary" @click.prevent="reset()">Reset</button> | ||||||
|             </div> |             </div> | ||||||
|  | 
 | ||||||
|  |             <search-history ref="searchHistory" :callback="updateSearch" :curSearch="data"></search-history> | ||||||
|  |         </div> | ||||||
|         <div v-else-if="results" class="results"> |         <div v-else-if="results" class="results"> | ||||||
|             <h4> |             <h4> | ||||||
|                 {{l('characterSearch.results')}} |                 {{l('characterSearch.results')}} | ||||||
| @ -44,21 +49,20 @@ | |||||||
|     import Modal from '../components/Modal.vue'; |     import Modal from '../components/Modal.vue'; | ||||||
|     import {characterImage} from './common'; |     import {characterImage} from './common'; | ||||||
|     import core from './core'; |     import core from './core'; | ||||||
|     import {Character, Connection} from './interfaces'; |     import { Character, Connection, SearchData, SearchKink } from './interfaces'; | ||||||
|     import l from './localize'; |     import l from './localize'; | ||||||
|     import UserView from './UserView.vue'; |     import UserView from './UserView.vue'; | ||||||
|     import * as _ from 'lodash'; |     import * as _ from 'lodash'; | ||||||
|     import {EventBus} from './preview/event-bus'; |     import {EventBus} from './preview/event-bus'; | ||||||
|  |     import CharacterSearchHistory from './CharacterSearchHistory.vue'; | ||||||
| 
 | 
 | ||||||
|     type Options = { |     type Options = { | ||||||
|         kinks: Kink[], |         kinks: SearchKink[], | ||||||
|         listitems: {id: string, name: string, value: string}[] |         listitems: {id: string, name: string, value: string}[] | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     let options: Options | undefined; |     let options: Options | undefined; | ||||||
| 
 | 
 | ||||||
|     type Kink = {id: number, name: string, description: string}; |  | ||||||
| 
 |  | ||||||
|     function sort(x: Character, y: Character): number { |     function sort(x: Character, y: Character): number { | ||||||
|         if(x.status === 'looking' && y.status !== 'looking') return -1; |         if(x.status === 'looking' && y.status !== 'looking') return -1; | ||||||
|         if(x.status !== 'looking' && y.status === 'looking') return 1; |         if(x.status !== 'looking' && y.status === 'looking') return 1; | ||||||
| @ -87,18 +91,9 @@ | |||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     interface Data { |  | ||||||
|         kinks: Kink[] |  | ||||||
|         genders: string[] |  | ||||||
|         orientations: string[] |  | ||||||
|         languages: string[] |  | ||||||
|         furryprefs: string[] |  | ||||||
|         roles: string[] |  | ||||||
|         positions: string[] |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     @Component({ |     @Component({ | ||||||
|         components: {modal: Modal, user: UserView, 'filterable-select': FilterableSelect, bbcode: BBCodeView(core.bbCodeParser)} |         components: {modal: Modal, user: UserView, 'filterable-select': FilterableSelect, bbcode: BBCodeView(core.bbCodeParser), 'search-history': CharacterSearchHistory} | ||||||
|     }) |     }) | ||||||
|     export default class CharacterSearch extends CustomDialog { |     export default class CharacterSearch extends CustomDialog { | ||||||
|         l = l; |         l = l; | ||||||
| @ -107,9 +102,9 @@ | |||||||
|         results: Character[] | undefined; |         results: Character[] | undefined; | ||||||
|         resultsComplete = false; |         resultsComplete = false; | ||||||
|         characterImage = characterImage; |         characterImage = characterImage; | ||||||
|         options!: Data; |         options!: SearchData; | ||||||
|         data: Data = {kinks: [], genders: [], orientations: [], languages: [], furryprefs: [], roles: [], positions: []}; |         data: SearchData = {kinks: [], genders: [], orientations: [], languages: [], furryprefs: [], roles: [], positions: []}; | ||||||
|         listItems: ReadonlyArray<keyof Data> = ['genders', 'orientations', 'languages', 'furryprefs', 'roles', 'positions']; |         listItems: ReadonlyArray<keyof SearchData> = ['genders', 'orientations', 'languages', 'furryprefs', 'roles', 'positions']; | ||||||
| 
 | 
 | ||||||
|         searchString = ''; |         searchString = ''; | ||||||
| 
 | 
 | ||||||
| @ -216,7 +211,7 @@ | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         filterKink(filter: RegExp, kink: Kink): boolean { |         filterKink(filter: RegExp, kink: SearchKink): boolean { | ||||||
|             if(this.data.kinks.length >= 5) |             if(this.data.kinks.length >= 5) | ||||||
|                 return this.data.kinks.indexOf(kink) !== -1; |                 return this.data.kinks.indexOf(kink) !== -1; | ||||||
|             return filter.test(kink.name); |             return filter.test(kink.name); | ||||||
| @ -232,6 +227,13 @@ | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |         updateSearch(data?: SearchData): void { | ||||||
|  |           if (data) { | ||||||
|  |             this.data = data; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|         submit(): void { |         submit(): void { | ||||||
|             if(this.results !== undefined) { |             if(this.results !== undefined) { | ||||||
|                 this.results = undefined; |                 this.results = undefined; | ||||||
| @ -240,11 +242,29 @@ | |||||||
|             this.error = ''; |             this.error = ''; | ||||||
|             const data: Connection.ClientCommands['FKS'] & {[key: string]: (string | number)[]} = {kinks: []}; |             const data: Connection.ClientCommands['FKS'] & {[key: string]: (string | number)[]} = {kinks: []}; | ||||||
|             for(const key in this.data) { |             for(const key in this.data) { | ||||||
|                 const item = this.data[<keyof Data>key]; |                 const item = this.data[<keyof SearchData>key]; | ||||||
|                 if(item.length > 0) |                 if(item.length > 0) | ||||||
|                     data[key] = key === 'kinks' ? (<Kink[]>item).map((x) => x.id) : (<string[]>item); |                     data[key] = key === 'kinks' ? (<SearchKink[]>item).map((x) => x.id) : (<string[]>item); | ||||||
|             } |             } | ||||||
|             core.connection.send('FKS', data); |             core.connection.send('FKS', data); | ||||||
|  | 
 | ||||||
|  |             // tslint:disable-next-line | ||||||
|  |             this.updateSearchHistory(this.data); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         showHistory(): void { | ||||||
|  |           (<CharacterSearchHistory>this.$refs.searchHistory).show(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         async updateSearchHistory(data: SearchData): Promise<void> { | ||||||
|  |             const history = (await core.settingsStore.get('searchHistory')) || []; | ||||||
|  |             const dataStr = JSON.stringify(data, null, 0); | ||||||
|  |             const filteredHistory = _.reject(history, (h: SearchData) => (JSON.stringify(h, null, 0) === dataStr)); | ||||||
|  |             const newHistory: SearchData[] = _.take(_.concat([data], filteredHistory), 15); | ||||||
|  | 
 | ||||||
|  |             await core.settingsStore.set('searchHistory', newHistory); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| </script> | </script> | ||||||
|  | |||||||
							
								
								
									
										130
									
								
								chat/CharacterSearchHistory.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								chat/CharacterSearchHistory.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,130 @@ | |||||||
|  | <template> | ||||||
|  |     <modal ref="dialog" action="Search history" buttonText="Select" @open="onMounted()" @submit="selectStatus" dialogClass="w-100 modal-lg"> | ||||||
|  |         <form class="search-history" v-if="history.length > 0"> | ||||||
|  |             <div class="form-row" v-for="(search, index) in history" :class="{ 'selected-row': (index === selectedSearch)}"> | ||||||
|  |                 <div class="form-col radio-col"> | ||||||
|  |                     <input type="radio" :id="'search_history_' + index" :name="'search_history_' + index" v-model="selectedSearch" v-bind:value="index" /> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="form-col content-col"> | ||||||
|  |                     <label class="custom-control-label" :for="'search_history_' + index" @dblclick="submit"> | ||||||
|  |                         {{describeSearch(search)}} | ||||||
|  |                     </label> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </form> | ||||||
|  |         <div v-else> | ||||||
|  |             <i>This character has no search history.</i> | ||||||
|  |         </div> | ||||||
|  |     </modal> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script lang="ts"> | ||||||
|  |     import { Component, Hook, Prop } from '@f-list/vue-ts'; | ||||||
|  |     import Modal from '../components/Modal.vue'; | ||||||
|  |     import Dropdown from '../components/Dropdown.vue'; | ||||||
|  |     import CustomDialog from '../components/custom_dialog'; | ||||||
|  |     import core from './core'; | ||||||
|  |     import { BBCodeView } from '../bbcode/view'; | ||||||
|  |     import * as _ from 'lodash'; | ||||||
|  |     import { SearchData } from './interfaces'; | ||||||
|  | 
 | ||||||
|  |     @Component({ | ||||||
|  |         components: {modal: Modal, dropdown: Dropdown, bbcode: BBCodeView(core.bbCodeParser)} | ||||||
|  |     }) | ||||||
|  |     export default class CharacterSearchHistory extends CustomDialog { | ||||||
|  |         @Prop({required: true}) | ||||||
|  |         readonly callback!: (searchData: SearchData) => void; | ||||||
|  | 
 | ||||||
|  |         @Prop({required: true}) | ||||||
|  |         readonly curSearch!: SearchData | undefined; | ||||||
|  | 
 | ||||||
|  |         history: SearchData[] = []; | ||||||
|  | 
 | ||||||
|  |         selectedSearch: number | null = null; | ||||||
|  | 
 | ||||||
|  |         @Hook('mounted') | ||||||
|  |         async onMounted(): Promise<void> { | ||||||
|  |             this.history = (await core.settingsStore.get('searchHistory')) || []; | ||||||
|  |             this.selectedSearch = null; | ||||||
|  | 
 | ||||||
|  |             if (this.curSearch) { | ||||||
|  |                 const cleanedSearch = JSON.stringify(this.curSearch, null, 0); | ||||||
|  | 
 | ||||||
|  |                 const index = _.findIndex( | ||||||
|  |                     this.history, | ||||||
|  |                   (c) => (JSON.stringify(c, null, 0) === cleanedSearch) | ||||||
|  |                 ); | ||||||
|  | 
 | ||||||
|  |                 if (index >= 0) { | ||||||
|  |                     this.selectedSearch = index; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         selectStatus(): void { | ||||||
|  |             if (this.selectedSearch !== null) { | ||||||
|  |                 this.callback(this.history[this.selectedSearch]); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         submit(e: Event): void { | ||||||
|  |           (<Modal>this.$refs.dialog).submit(e); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         describeSearch(searchData: SearchData): string { | ||||||
|  |             return _.join( | ||||||
|  |                 _.map( | ||||||
|  |                     // tslint:disable-next-line no-unsafe-any no-any | ||||||
|  |                     _.flatten(_.map(searchData as any)), | ||||||
|  |                     // tslint:disable-next-line no-unsafe-any no-any | ||||||
|  |                     (v) => _.get(v, 'name', v) | ||||||
|  |                 ), | ||||||
|  |                 ', ' | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style lang="scss"> | ||||||
|  |     .search-history { | ||||||
|  |         .radio-col { | ||||||
|  |             display: none; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         label::before { | ||||||
|  |             display:none !important; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .content-col { | ||||||
|  |             min-width: 100%; | ||||||
|  | 
 | ||||||
|  |             label { | ||||||
|  |                 min-width: 100%; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .form-row { | ||||||
|  |             margin-bottom: 10px; | ||||||
|  |             padding: 3px; | ||||||
|  | 
 | ||||||
|  |             border: 1px solid rgba(0,0,0,0); | ||||||
|  |             border-radius: 2px; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .form-row:hover { | ||||||
|  |             background-color: #20203e; | ||||||
|  |             border: 1px solid #2d2d6b; | ||||||
|  |             border-radius: 2px; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .selected-row, | ||||||
|  |         .form-row.selected-row:hover { | ||||||
|  |             background-color: #343461; | ||||||
|  |             border: 1px solid #6565b2; | ||||||
|  |             border-radius: 2px; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | </style> | ||||||
| @ -186,3 +186,9 @@ import {InlineDisplayMode} from '../interfaces'; | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| </script> | </script> | ||||||
|  | 
 | ||||||
|  | <style lang="scss"> | ||||||
|  |     .modal-footer { | ||||||
|  |         min-height: initial; | ||||||
|  |     } | ||||||
|  | </style> | ||||||
|  | |||||||
| @ -1,12 +1,12 @@ | |||||||
| <template> | <template> | ||||||
|     <modal action="Status message history" buttonText="Select" @open="onMounted()" @submit="selectStatus" dialogClass="w-100 modal-lg"> |     <modal ref="dialog" action="Status message history" buttonText="Select" @open="onMounted()" @submit="selectStatus" dialogClass="w-100 modal-lg"> | ||||||
|         <form class="status-picker" v-if="history.length > 0"> |         <form class="status-picker" v-if="history.length > 0"> | ||||||
|             <div class="form-row" v-for="(historicStatus, index) in history" :class="{ 'selected-row': (index === selectedStatus)}"> |             <div class="form-row" v-for="(historicStatus, index) in history" :class="{ 'selected-row': (index === selectedStatus)}"> | ||||||
|                 <div class="form-col radio-col"> |                 <div class="form-col radio-col"> | ||||||
|                     <input type="radio" :id="'history_status_' + index" :name="'history_status_' + index" v-model="selectedStatus" v-bind:value="index" /> |                     <input type="radio" :id="'history_status_' + index" :name="'history_status_' + index" v-model="selectedStatus" v-bind:value="index" /> | ||||||
|                 </div> |                 </div> | ||||||
|                 <div class="form-col content-col"> |                 <div class="form-col content-col"> | ||||||
|                     <label class="custom-control-label" :for="'history_status_' + index"> |                     <label class="custom-control-label" :for="'history_status_' + index" @dblclick="submit"> | ||||||
|                         <bbcode :text="historicStatus"></bbcode> |                         <bbcode :text="historicStatus"></bbcode> | ||||||
|                     </label> |                     </label> | ||||||
|                 </div> |                 </div> | ||||||
| @ -61,6 +61,11 @@ | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |         submit(e: Event): void { | ||||||
|  |           (<Modal>this.$refs.dialog).submit(e); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|         selectStatus(): void { |         selectStatus(): void { | ||||||
|             if (this.selectedStatus !== null) { |             if (this.selectedStatus !== null) { | ||||||
|                 this.callback(this.history[this.selectedStatus]); |                 this.callback(this.history[this.selectedStatus]); | ||||||
|  | |||||||
| @ -143,6 +143,19 @@ export interface Logs { | |||||||
|     canZip: boolean; |     canZip: boolean; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export type SearchKink = {id: number, name: string, description: string}; | ||||||
|  | 
 | ||||||
|  | export interface SearchData { | ||||||
|  |     kinks: SearchKink[] | ||||||
|  |     genders: string[] | ||||||
|  |     orientations: string[] | ||||||
|  |     languages: string[] | ||||||
|  |     furryprefs: string[] | ||||||
|  |     roles: string[] | ||||||
|  |     positions: string[] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| export namespace Settings { | export namespace Settings { | ||||||
|     export type Keys = { |     export type Keys = { | ||||||
|         settings: Settings |         settings: Settings | ||||||
| @ -153,6 +166,7 @@ export namespace Settings { | |||||||
|         recentChannels: Conversation.RecentChannelConversation[] |         recentChannels: Conversation.RecentChannelConversation[] | ||||||
|         hiddenUsers: string[] |         hiddenUsers: string[] | ||||||
|         statusHistory: string[] |         statusHistory: string[] | ||||||
|  |         searchHistory: SearchData[] | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     export interface Store { |     export interface Store { | ||||||
|  | |||||||
| @ -126,7 +126,8 @@ export class ImagePreviewMutator { | |||||||
|         this.add('youtube.com', this.getBaseJsMutatorScript(['video']), undefined, 'dom-ready'); |         this.add('youtube.com', this.getBaseJsMutatorScript(['video']), undefined, 'dom-ready'); | ||||||
|         this.add('instantfap.com', this.getBaseJsMutatorScript(['#post video', '#post img'])); |         this.add('instantfap.com', this.getBaseJsMutatorScript(['#post video', '#post img'])); | ||||||
|         this.add('webmshare.com', this.getBaseJsMutatorScript(['video'])); |         this.add('webmshare.com', this.getBaseJsMutatorScript(['video'])); | ||||||
|         this.add('pornhub.com', this.getBaseJsMutatorScript(['.mainPlayerDiv video[preload="auto"]', '.mainPlayerDiv video[preload="none"]', '.mainPlayerDiv video', '.photoImageSection img'])); |         this.add('pornhub.com', this.getBaseJsMutatorScript(['#video, video', '.mainPlayerDiv video', '.photoImageSection img'])); | ||||||
|  |         this.add('vimeo.com', this.getBaseJsMutatorScript(['#video, video', '#image, img'])); | ||||||
|         this.add('sex.com', this.getBaseJsMutatorScript(['.image_frame video', '.image_frame img'])); |         this.add('sex.com', this.getBaseJsMutatorScript(['.image_frame video', '.image_frame img'])); | ||||||
|         this.add('redirect.media.tumblr.com', this.getBaseJsMutatorScript(['picture video', 'picture img'])); |         this.add('redirect.media.tumblr.com', this.getBaseJsMutatorScript(['picture video', 'picture img'])); | ||||||
|         this.add('postimg.cc', this.getBaseJsMutatorScript(['video', '#main-image'])); |         this.add('postimg.cc', this.getBaseJsMutatorScript(['video', '#main-image'])); | ||||||
| @ -199,7 +200,7 @@ export class ImagePreviewMutator { | |||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     getBaseJsMutatorScript(elSelector: string[], skipElementRemove: boolean = false): string { |     getBaseJsMutatorScript(elSelector: string[], skipElementRemove: boolean = false, safeTags: string[] = []): string { | ||||||
|         return `const { ipcRenderer } = require('electron');
 |         return `const { ipcRenderer } = require('electron');
 | ||||||
|             const body = document.querySelector('body'); |             const body = document.querySelector('body'); | ||||||
|             const html = document.querySelector('html'); |             const html = document.querySelector('html'); | ||||||
| @ -252,12 +253,14 @@ export class ImagePreviewMutator { | |||||||
|             body.style = 'border: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important;' |             body.style = 'border: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important;' | ||||||
|                 + 'width: 100% !important; height: 100% !important; opacity: 1 !important;' |                 + 'width: 100% !important; height: 100% !important; opacity: 1 !important;' | ||||||
|                 + 'top: 0 !important; left: 0 !important; position: absolute !important;' |                 + 'top: 0 !important; left: 0 !important; position: absolute !important;' | ||||||
|                 + 'min-width: unset !important; min-height: unset !important; max-width: unset !important; max-height: unset !important;'; |                 + 'min-width: unset !important; min-height: unset !important; max-width: unset !important; max-height: unset !important;' | ||||||
|  |                 + 'display: block !important; visibility: visible !important'; | ||||||
| 
 | 
 | ||||||
|             img.style = 'object-position: top left !important; object-fit: contain !important;' |             img.style = 'object-position: top left !important; object-fit: contain !important;' | ||||||
|                 + 'width: 100% !important; height: 100% !important; opacity: 1 !important;' |                 + 'width: 100% !important; height: 100% !important; opacity: 1 !important;' | ||||||
|                 + 'margin: 0 !imporant; border: 0 !important; padding: 0 !important;' |                 + 'margin: 0 !imporant; border: 0 !important; padding: 0 !important;' | ||||||
|                 + 'min-width: unset !important; min-height: unset !important; max-width: unset !important; max-height: unset !important;'; |                 + 'min-width: unset !important; min-height: unset !important; max-width: unset !important; max-height: unset !important;' | ||||||
|  |                 + 'display: block !important; visibility: visible !important'; | ||||||
| 
 | 
 | ||||||
|             img.class = ''; |             img.class = ''; | ||||||
|             el.class = ''; |             el.class = ''; | ||||||
| @ -266,7 +269,8 @@ export class ImagePreviewMutator { | |||||||
|             html.style = 'border: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important;' |             html.style = 'border: 0 !important; padding: 0 !important; margin: 0 !important; overflow: hidden !important;' | ||||||
|                 + 'width: 100% !important; height: 100% !important; opacity: 1 !important;' |                 + 'width: 100% !important; height: 100% !important; opacity: 1 !important;' | ||||||
|                 + 'top: 0 !important; left: 0 !important; position: absolute !important;' |                 + 'top: 0 !important; left: 0 !important; position: absolute !important;' | ||||||
|                 + 'min-width: unset !important; min-height: unset !important; max-width: unset !important; max-height: unset !important;'; |                 + 'min-width: unset !important; min-height: unset !important; max-width: unset !important; max-height: unset !important;' | ||||||
|  |                 + 'display: block !important; visibility: visible !important'; | ||||||
| 
 | 
 | ||||||
|             ${this.debug ? "console.log('Wrapper', el);" : ''} |             ${this.debug ? "console.log('Wrapper', el);" : ''} | ||||||
| 
 | 
 | ||||||
| @ -322,8 +326,14 @@ export class ImagePreviewMutator { | |||||||
| 
 | 
 | ||||||
|             let removeList = []; |             let removeList = []; | ||||||
|             const safeIds = ['flistWrapper', 'flistError', 'flistHider']; |             const safeIds = ['flistWrapper', 'flistError', 'flistHider']; | ||||||
|  |             const safeTags = [${_.map(safeTags, (t) => `'${t.toLowerCase()}'`).join(',')}]; | ||||||
| 
 | 
 | ||||||
|             body.childNodes.forEach((el) => ((safeIds.indexOf(el.id) < 0) ? removeList.push(el) : true)); |             body.childNodes.forEach((el) => ( | ||||||
|  |                 ( | ||||||
|  |                     (safeIds.indexOf(el.id) < 0) | ||||||
|  |                     && ((!el.tagName) || (safeTags.indexOf(el.tagName.toLowerCase())) < 0) | ||||||
|  |                 ) ? removeList.push(el) : true) | ||||||
|  |             ); | ||||||
| 
 | 
 | ||||||
|             ${skipElementRemove ? '' : 'removeList.forEach((el) => el.remove());'} |             ${skipElementRemove ? '' : 'removeList.forEach((el) => el.remove());'} | ||||||
|             removeList = []; |             removeList = []; | ||||||
|  | |||||||
| @ -41,4 +41,7 @@ | |||||||
| 
 | 
 | ||||||
|     [url=https://www.pornhub.com/view_video.php?viewkey=ph5b2c03dc1e23b]Test[/url] |     [url=https://www.pornhub.com/view_video.php?viewkey=ph5b2c03dc1e23b]Test[/url] | ||||||
| 
 | 
 | ||||||
|  |     [url=https://vimeo.com/265884960]Test[/url] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -43,6 +43,7 @@ This repository contains a heavily customized version of the mainline F-Chat 3.0 | |||||||
|     *    Display match score in search results |     *    Display match score in search results | ||||||
|     *    Current search filters are listed in the search dialog |     *    Current search filters are listed in the search dialog | ||||||
|     *    Search filters can be reset |     *    Search filters can be reset | ||||||
|  |     *    Last 15 searches are stored and can be accessed from the 'Search' dialog | ||||||
| *   Character status | *   Character status | ||||||
|     *    Last 10 status messages are stored and can be accessed from the 'Set status' dialog |     *    Last 10 status messages are stored and can be accessed from the 'Set status' dialog | ||||||
| *   General | *   General | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user