Profile image optimization

This commit is contained in:
Mr. Stallion 2021-01-01 18:13:09 -06:00
parent ce26885a90
commit 13db853dc3
4 changed files with 79 additions and 16 deletions

View File

@ -2,6 +2,7 @@
## Canary
* Skip button for auto-post ads
* Image tab on the character profile view now loads up faster
## 1.8.0

View File

@ -1,4 +1,3 @@
import {InlineDisplayMode} from '../interfaces';
<template>
<div style="display:flex; flex-direction: column; height:100%; justify-content: center">
<div class="card bg-light" style="width:400px;max-width:100%;margin:0 auto" v-if="!connected">

View File

@ -73,6 +73,8 @@
import {Component, Hook, Prop, Watch} from '@f-list/vue-ts';
import Vue from 'vue';
import log from 'electron-log'; //tslint:disable-line:match-default-export-name
import {StandardBBCodeParser} from '../../bbcode/standard';
import {BBCodeView} from '../../bbcode/view';
import { CharacterCacheRecord } from '../../learn/profile-cache';
@ -95,7 +97,7 @@
import { CharacterImage, SimpleCharacter } from '../../interfaces';
const CHARACTER_CACHE_EXPIRE = 7 * 24 * 60 * 60 * 1000; // 7 days (milliseconds)
const CHARACTER_META_CACHE_EXPIRE = 7 * 24 * 60 * 60 * 1000; // 10 days (milliseconds)
const CHARACTER_META_CACHE_EXPIRE = 7 * 24 * 60 * 60 * 1000; // 7 days (milliseconds)
interface ShowableVueTab extends Vue {
show?(): void
@ -198,8 +200,14 @@
return core.state.settings.risingAdScore;
}
async reload(): Promise<void> {
await this.load(true, true);
const target = <ShowableVueTab>this.$refs[`tab${this.tab}`];
//tslint:disable-next-line:no-unbound-method
if(typeof target.show === 'function') target.show();
}
@ -355,6 +363,8 @@
}
private async _getCharacter(skipCache: boolean = false): Promise<void> {
log.debug('profile.getCharacter', { name: this.name } );
this.character = undefined;
this.friends = null;
this.groups = null;
@ -373,20 +383,24 @@
standardParser.inlines = this.character.character.inlines;
if ((cache) && (cache.meta)) {
this.guestbook = cache.meta.guestbook;
this.friends = cache.meta.friends;
this.groups = cache.meta.groups;
this.images = cache.meta.images;
}
if (
(cache && !skipCache)
&& (cache.meta)
&& (cache.meta.lastMetaFetched)
&& (Date.now() - cache.meta.lastMetaFetched.getTime() > CHARACTER_META_CACHE_EXPIRE)
) {
this.guestbook = cache.meta.guestbook;
this.friends = cache.meta.friends;
this.groups = cache.meta.groups;
this.images = cache.meta.images;
// do nothing
} else {
// No await on purpose:
// tslint:disable-next-line no-floating-promises
this.updateMeta(this.name);
this.updateMeta(this.name).catch(err => console.error('profile.updateMeta', err));
}
// console.log('LoadChar', this.name, this.character);

View File

@ -1,7 +1,7 @@
<template>
<!-- <div class="character-images row">-->
<div class="character-images">
<div v-show="loading" class="alert alert-info">Loading images.</div>
<div v-show="((loading) && (images.length === 0))" class="alert alert-info">Loading images.</div>
<template v-if="!loading">
<div class="images-navigate-up">
<i class="fa fa-angle-up"></i>
@ -24,6 +24,7 @@
</template>
<script lang="ts">
import log from 'electron-log'; //tslint:disable-line:match-default-export-name
import {Component, Prop} from '@f-list/vue-ts';
import Vue from 'vue';
import {CharacterImage} from '../../interfaces';
@ -31,6 +32,8 @@
import {methods} from './data_store';
import {Character} from './interfaces';
import core from '../../chat/core';
import _ from 'lodash';
@Component
export default class ImagesView extends Vue {
@ -50,36 +53,82 @@
imageUrl = (image: CharacterImage) => methods.imageUrl(image);
thumbUrl = (image: CharacterImage) => methods.imageThumbUrl(image);
async show(): Promise<void> {
show(): void {
log.debug('profile.images.show', { shown: this.shown, loading: this.loading });
if (this.shown) {
return;
}
this.images = this.resolveImages();
// this promise is intentionally not part of a chain
this.showAsync().catch((err) => log.error('profile.images.error', { err }));
}
async showAsync(): Promise<void> {
log.debug('profile.images.show.async', { shown: this.shown, loading: this.loading });
if(this.shown) return;
try {
this.error = '';
this.shown = true;
this.loading = true;
this.images = await this.resolveImages();
} catch(e) {
this.images = await this.resolveImagesAsync();
} catch(err) {
this.shown = false;
if(Utils.isJSONError(e))
this.error = <string>e.response.data.error;
Utils.ajaxError(e, 'Unable to load images.');
if(Utils.isJSONError(err))
this.error = <string>err.response.data.error;
Utils.ajaxError(err, 'Unable to refresh images.');
log.error('profile.images.show.async.error', { err });
}
this.loading = false;
}
async resolveImages(): Promise<CharacterImage[]> {
async resolveImagesAsync(): Promise<CharacterImage[]> {
log.debug('profile.images.async.injected', { count: this.injectedImages ? this.injectedImages.length : 0 });
if ((this.injectedImages) && (this.injectedImages.length)) {
return this.injectedImages;
}
const c = await core.cache.profileCache.get(this.character.character.name);
log.debug('profile.images.async.cache', { count: _.get(c, 'meta.images.length') });
if ((c) && (c.meta) && (c.meta.images)) {
return c.meta.images;
}
return methods.imagesGet(this.character.character.id);
const images = await methods.imagesGet(this.character.character.id);
log.debug('profile.images.async.api', { count: images.length });
return images;
}
resolveImages(): CharacterImage[] {
log.debug('profile.images.sync.injected', { count: this.injectedImages ? this.injectedImages.length : 0 });
if ((this.injectedImages) && (this.injectedImages.length)) {
return this.injectedImages;
}
const c = core.cache.profileCache.getSync(this.character.character.name);
log.debug('profile.images.sync.cache', { count: _.get(c, 'meta.images.length') });
if ((c) && (c.meta) && (c.meta.images)) {
return c.meta.images;
}
return [];
}
handleImageClick(e: MouseEvent, image: CharacterImage): void {
if(this.usePreview) {
this.previewImage = methods.imageUrl(image);