Status message history
This commit is contained in:
parent
0e428a44bc
commit
79cfb2b938
|
@ -286,7 +286,7 @@
|
|||
|
||||
.search-spinner {
|
||||
float: right;
|
||||
animation: search-spin 4s linear infinite;
|
||||
animation: search-spin 0.75s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
class="nav-link" href="#" @click.prevent="setMode(mode)">{{l('channel.mode.' + mode)}}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a @click.prevent="toggleNonMatchingAds()" :class="{active: showNonMatchingAds, disabled: !showNonMatchingAds}" v-show="(conversation.mode == 'both' || conversation.mode == 'ads')"
|
||||
<a @click.prevent="toggleNonMatchingAds()" :class="{active: showNonMatchingAds}" v-show="(conversation.mode == 'both' || conversation.mode == 'ads')"
|
||||
class="nav-link" href="#">Non-Matching</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
<template>
|
||||
<modal action="Status message history" buttonText="Select" @open="onMounted()" @submit="selectStatus" dialogClass="w-100 modal-lg">
|
||||
<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-col radio-col">
|
||||
<input type="radio" :id="'history_status_' + index" :name="'history_status_' + index" v-model="selectedStatus" v-bind:value="index" />
|
||||
</div>
|
||||
<div class="form-col content-col">
|
||||
<label class="custom-control-label" :for="'history_status_' + index">
|
||||
<bbcode :text="historicStatus"></bbcode>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div v-else>
|
||||
<i>This character has no status message 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';
|
||||
|
||||
@Component({
|
||||
components: {modal: Modal, dropdown: Dropdown, bbcode: BBCodeView(core.bbCodeParser)}
|
||||
})
|
||||
export default class StatusPicker extends CustomDialog {
|
||||
@Prop({required: true})
|
||||
readonly callback!: (statusMessage: string) => void;
|
||||
|
||||
@Prop({required: true})
|
||||
readonly curStatus!: string | undefined;
|
||||
|
||||
history: string[] = [];
|
||||
|
||||
selectedStatus: number | null = null;
|
||||
|
||||
@Hook('mounted')
|
||||
async onMounted(): Promise<void> {
|
||||
this.history = (await core.settingsStore.get('statusHistory')) || [];
|
||||
this.selectedStatus = null;
|
||||
|
||||
if ((this.curStatus) && (this.curStatus.trim() !== '')) {
|
||||
const cleanedStatus = this.curStatus.toLowerCase().trim();
|
||||
|
||||
const index = _.findIndex(
|
||||
this.history,
|
||||
(c: string) => (c.toString().toLowerCase().trim() === cleanedStatus)
|
||||
);
|
||||
|
||||
if (index >= 0) {
|
||||
this.selectedStatus = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
selectStatus(): void {
|
||||
if (this.selectedStatus !== null) {
|
||||
this.callback(this.history[this.selectedStatus]);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.status-picker {
|
||||
.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>
|
|
@ -17,6 +17,11 @@
|
|||
</div>
|
||||
</editor>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="button" @click="showStatusPicker" class="btn btn-outline-secondary">History</button>
|
||||
</div>
|
||||
|
||||
<status-picker ref="statusPicker" :callback="insertStatusMessage" :curStatus="enteredText"></status-picker>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
|
@ -31,9 +36,11 @@
|
|||
import {Character, userStatuses} from './interfaces';
|
||||
import l from './localize';
|
||||
import {getStatusIcon} from './UserView.vue';
|
||||
import StatusPicker from './StatusPicker.vue';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
@Component({
|
||||
components: {modal: Modal, editor: Editor, dropdown: Dropdown}
|
||||
components: {modal: Modal, editor: Editor, dropdown: Dropdown, 'status-picker': StatusPicker}
|
||||
})
|
||||
export default class StatusSwitcher extends CustomDialog {
|
||||
selectedStatus: Character.Status | undefined;
|
||||
|
@ -65,11 +72,36 @@
|
|||
|
||||
setStatus(): void {
|
||||
core.connection.send('STA', {status: this.status, statusmsg: this.text});
|
||||
|
||||
// tslint:disable-next-line
|
||||
this.updateHistory(this.text);
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.selectedStatus = undefined;
|
||||
this.enteredText = undefined;
|
||||
}
|
||||
|
||||
insertStatusMessage(statusMessage: string): void {
|
||||
this.text = statusMessage;
|
||||
}
|
||||
|
||||
|
||||
async updateHistory(statusMessage: string): Promise<void> {
|
||||
if ((!statusMessage) || (statusMessage.trim() === '')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const curHistory: string[] = (await core.settingsStore.get('statusHistory')) || [];
|
||||
const statusMessageClean = statusMessage.toString().trim().toLowerCase();
|
||||
const filteredHistory: string[] = _.reject(curHistory, (c: string) => (c.toString().trim().toLowerCase() === statusMessageClean));
|
||||
const newHistory: string[] = _.take(_.concat([statusMessage], filteredHistory), 10);
|
||||
|
||||
await core.settingsStore.set('statusHistory', newHistory);
|
||||
}
|
||||
|
||||
showStatusPicker(): void {
|
||||
(<StatusPicker>this.$refs['statusPicker']).show();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -145,13 +145,14 @@ export interface Logs {
|
|||
|
||||
export namespace Settings {
|
||||
export type Keys = {
|
||||
settings: Settings,
|
||||
pinned: {channels: string[], private: string[]},
|
||||
settings: Settings
|
||||
pinned: {channels: string[], private: string[]}
|
||||
conversationSettings: {[key: string]: Conversation.Settings | undefined}
|
||||
modes: {[key: string]: Channel.Mode | undefined}
|
||||
recent: Conversation.RecentPrivateConversation[]
|
||||
recentChannels: Conversation.RecentChannelConversation[]
|
||||
hiddenUsers: string[]
|
||||
statusHistory: string[]
|
||||
};
|
||||
|
||||
export interface Store {
|
||||
|
|
|
@ -17,4 +17,4 @@ export default class CustomDialog extends Vue {
|
|||
hide(): void {
|
||||
this.dialog.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,4 +12,4 @@
|
|||
<script type="text/javascript" src="common.js"></script>
|
||||
<script type="text/javascript" src="chat.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
17
readme.md
17
readme.md
|
@ -7,10 +7,11 @@ This repository contains a heavily customized version of the mainline F-Chat 3.0
|
|||
|
||||
1. **Profile matching** automatically compares your profile with others to determine with whom you are compatible.
|
||||
1. **Automatic ad posting** repeatedly posts and rotates ads on selected channels.
|
||||
1. **Link previews** pop up shows a preview of an image when you hover your mouse over a link.
|
||||
1. **Link previews** popup shows a preview of an image / video when you hover your mouse over a link.
|
||||
1. **Caching** speeds up profile loads and other actions.
|
||||
|
||||
|
||||
### More Details
|
||||
### More Detailed Differences
|
||||
|
||||
* Ads view
|
||||
* Highlight ads from characters most interesting to you
|
||||
|
@ -42,10 +43,13 @@ This repository contains a heavily customized version of the mainline F-Chat 3.0
|
|||
* Display match score in search results
|
||||
* Current search filters are listed in the search dialog
|
||||
* Search filters can be reset
|
||||
* Character status
|
||||
* Last 10 status messages are stored and can be accessed from the 'Set status' dialog
|
||||
* General
|
||||
* Character profiles, guestbooks, friend lists, and image lists are cached for faster access.
|
||||
* Character profiles, guestbooks, friend lists, and image lists are cached for faster access
|
||||
* Conversation dialog can be opened by typing in a character name
|
||||
* Message search also checks character names
|
||||
* Message search matches character names
|
||||
* PM list shows characters' online status as a colored icon
|
||||
|
||||
|
||||
## How to Set Up Ads
|
||||
|
@ -76,10 +80,9 @@ This repository contains a heavily customized version of the mainline F-Chat 3.0
|
|||
* Save character's status messages
|
||||
* Conversation bot API
|
||||
* 'Filter unmatching ads' is not channel specific -- it's either on everywhere or nowhere
|
||||
* AD UI Cleanup / hide to popovers
|
||||
* AD UI Cleanup / hide to popovers?
|
||||
* image loading animation
|
||||
* Ad cache is broken
|
||||
* Show online / offline status on PM list
|
||||
* Usually submissive vs usually submissive shows up as 'maybe'?
|
||||
|
||||
|
||||
# F-List Exported
|
||||
|
|
Loading…
Reference in New Issue