Status message history

This commit is contained in:
Mr. Stallion 2020-03-21 13:35:22 -05:00
parent 0e428a44bc
commit 79cfb2b938
8 changed files with 162 additions and 15 deletions

View File

@ -286,7 +286,7 @@
.search-spinner {
float: right;
animation: search-spin 4s linear infinite;
animation: search-spin 0.75s linear infinite;
}
}

View File

@ -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>

111
chat/StatusPicker.vue Normal file
View File

@ -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>

View File

@ -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>

View File

@ -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 {

View File

@ -17,4 +17,4 @@ export default class CustomDialog extends Vue {
hide(): void {
this.dialog.hide();
}
}
}

View File

@ -12,4 +12,4 @@
<script type="text/javascript" src="common.js"></script>
<script type="text/javascript" src="chat.js"></script>
</body>
</html>
</html>

View File

@ -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