Deck (#6504)
* wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip
This commit is contained in:
@@ -1,18 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
<mk-container :show-header="props.design === 0" :naked="props.design === 2">
|
||||
<template #header><fa :icon="faChartBar"/>{{ $t('_widgets.activity') }}</template>
|
||||
<template #func><button @click="toggleView()" class="_button"><fa :icon="faSort"/></button></template>
|
||||
<mk-container :show-header="props.showHeader" :naked="props.transparent">
|
||||
<template #header><fa :icon="faChartBar"/>{{ $t('_widgets.activity') }}</template>
|
||||
<template #func><button @click="toggleView()" class="_button"><fa :icon="faSort"/></button></template>
|
||||
|
||||
<div>
|
||||
<mk-loading v-if="fetching"/>
|
||||
<template v-else>
|
||||
<x-calendar v-show="props.view === 0" :data="[].concat(activity)"/>
|
||||
<x-chart v-show="props.view === 1" :data="[].concat(activity)"/>
|
||||
</template>
|
||||
</div>
|
||||
</mk-container>
|
||||
</div>
|
||||
<div>
|
||||
<mk-loading v-if="fetching"/>
|
||||
<template v-else>
|
||||
<x-calendar v-show="props.view === 0" :data="[].concat(activity)"/>
|
||||
<x-chart v-show="props.view === 1" :data="[].concat(activity)"/>
|
||||
</template>
|
||||
</div>
|
||||
</mk-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -25,8 +23,19 @@ import XChart from './activity.chart.vue';
|
||||
export default define({
|
||||
name: 'activity',
|
||||
props: () => ({
|
||||
design: 0,
|
||||
view: 0
|
||||
showHeader: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
transparent: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
view: {
|
||||
type: 'number',
|
||||
default: 0,
|
||||
hidden: true,
|
||||
},
|
||||
})
|
||||
}).extend({
|
||||
components: {
|
||||
@@ -57,14 +66,6 @@ export default define({
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
func() {
|
||||
if (this.props.design === 2) {
|
||||
this.props.design = 0;
|
||||
} else {
|
||||
this.props.design++;
|
||||
}
|
||||
this.save();
|
||||
},
|
||||
toggleView() {
|
||||
if (this.props.view === 1) {
|
||||
this.props.view = 0;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="mkw-calendar" :class="{ _panel: props.design === 0 }">
|
||||
<div class="mkw-calendar" :class="{ _panel: !props.transparent }">
|
||||
<div class="calendar" :data-is-holiday="isHoliday">
|
||||
<p class="month-and-year">
|
||||
<span class="year">{{ $t('yearX', { year }) }}</span>
|
||||
@@ -37,7 +37,10 @@ import define from './define';
|
||||
export default define({
|
||||
name: 'calendar',
|
||||
props: () => ({
|
||||
design: 0
|
||||
transparent: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
}).extend({
|
||||
data() {
|
||||
@@ -62,14 +65,6 @@ export default define({
|
||||
clearInterval(this.clock);
|
||||
},
|
||||
methods: {
|
||||
func() {
|
||||
if (this.props.design === 2) {
|
||||
this.props.design = 0;
|
||||
} else {
|
||||
this.props.design++;
|
||||
}
|
||||
this.save();
|
||||
},
|
||||
tick() {
|
||||
const now = new Date();
|
||||
const nd = now.getDate();
|
||||
|
@@ -1,11 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<mk-container :naked="props.style % 2 === 0" :show-header="false">
|
||||
<div class="vubelbmv">
|
||||
<mk-analog-clock class="clock" :smooth="props.style < 2"/>
|
||||
</div>
|
||||
</mk-container>
|
||||
</div>
|
||||
<mk-container :naked="props.transparent" :show-header="false">
|
||||
<div class="vubelbmv">
|
||||
<mk-analog-clock class="clock"/>
|
||||
</div>
|
||||
</mk-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -16,19 +14,16 @@ import MkAnalogClock from '../components/analog-clock.vue';
|
||||
export default define({
|
||||
name: 'clock',
|
||||
props: () => ({
|
||||
style: 0
|
||||
transparent: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
}).extend({
|
||||
components: {
|
||||
MkContainer,
|
||||
MkAnalogClock
|
||||
},
|
||||
methods: {
|
||||
func() {
|
||||
this.props.style = (this.props.style + 1) % 4;
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import Vue from 'vue';
|
||||
import { Form } from '../scripts/form';
|
||||
|
||||
export default function <T extends object>(data: {
|
||||
export default function <T extends Form>(data: {
|
||||
name: string;
|
||||
props?: () => T;
|
||||
}) {
|
||||
@@ -15,22 +16,22 @@ export default function <T extends object>(data: {
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
bakedOldProps: null
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
id(): string {
|
||||
return this.widget.id;
|
||||
},
|
||||
|
||||
props(): T {
|
||||
props(): Record<string, any> {
|
||||
return this.widget.data;
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
bakedOldProps: null
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.mergeProps();
|
||||
|
||||
@@ -45,11 +46,26 @@ export default function <T extends object>(data: {
|
||||
const defaultProps = data.props();
|
||||
for (const prop of Object.keys(defaultProps)) {
|
||||
if (this.props.hasOwnProperty(prop)) continue;
|
||||
Vue.set(this.props, prop, defaultProps[prop]);
|
||||
Vue.set(this.props, prop, defaultProps[prop].default);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async setting() {
|
||||
const form = data.props();
|
||||
for (const item of Object.keys(form)) {
|
||||
form[item].default = this.props[item];
|
||||
}
|
||||
const { canceled, result } = await this.$root.form(data.name, form);
|
||||
if (canceled) return;
|
||||
|
||||
for (const key of Object.keys(result)) {
|
||||
Vue.set(this.props, key, result[key]);
|
||||
}
|
||||
|
||||
this.save();
|
||||
},
|
||||
|
||||
save() {
|
||||
this.$store.commit('deviceUser/updateWidget', this.widget);
|
||||
}
|
||||
|
75
src/client/widgets/digital-clock.vue
Normal file
75
src/client/widgets/digital-clock.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div class="mkw-digitalClock" :class="{ _panel: !props.transparent }" :style="{ fontSize: `${props.fontSize}em` }">
|
||||
<span>
|
||||
<span v-text="hh"></span>
|
||||
<span :style="{ visibility: showColon ? 'visible' : 'hidden' }">:</span>
|
||||
<span v-text="mm"></span>
|
||||
<span :style="{ visibility: showColon ? 'visible' : 'hidden' }">:</span>
|
||||
<span v-text="ss"></span>
|
||||
<span :style="{ visibility: showColon ? 'visible' : 'hidden' }" v-if="props.showMs">:</span>
|
||||
<span v-text="ms" v-if="props.showMs"></span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import define from './define';
|
||||
|
||||
export default define({
|
||||
name: 'digitalClock',
|
||||
props: () => ({
|
||||
transparent: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
fontSize: {
|
||||
type: 'number',
|
||||
default: 1.5,
|
||||
step: 0.1,
|
||||
},
|
||||
showMs: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
}).extend({
|
||||
data() {
|
||||
return {
|
||||
clock: null,
|
||||
hh: null,
|
||||
mm: null,
|
||||
ss: null,
|
||||
ms: null,
|
||||
showColon: true,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.tick();
|
||||
this.$watch('props.showMs', () => {
|
||||
if (this.clock) clearInterval(this.clock);
|
||||
this.clock = setInterval(this.tick, this.props.showMs ? 10 : 1000);
|
||||
}, { immediate: true });
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.clock);
|
||||
},
|
||||
methods: {
|
||||
tick() {
|
||||
const now = new Date();
|
||||
this.hh = now.getHours().toString().padStart(2, '0');
|
||||
this.mm = now.getMinutes().toString().padStart(2, '0');
|
||||
this.ss = now.getSeconds().toString().padStart(2, '0');
|
||||
this.ms = Math.floor(now.getMilliseconds() / 10).toString().padStart(2, '0');
|
||||
this.showColon = now.getSeconds() % 2 === 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mkw-digitalClock {
|
||||
padding: 16px 0;
|
||||
font-family: Lucida Console, Courier, monospace;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
@@ -10,3 +10,17 @@ Vue.component('mkw-trends', () => import('./trends.vue').then(m => m.default));
|
||||
Vue.component('mkw-clock', () => import('./clock.vue').then(m => m.default));
|
||||
Vue.component('mkw-activity', () => import('./activity.vue').then(m => m.default));
|
||||
Vue.component('mkw-photos', () => import('./photos.vue').then(m => m.default));
|
||||
Vue.component('mkw-digitalClock', () => import('./digital-clock.vue').then(m => m.default));
|
||||
|
||||
export const widgets = [
|
||||
'memo',
|
||||
'notifications',
|
||||
'timeline',
|
||||
'calendar',
|
||||
'rss',
|
||||
'trends',
|
||||
'clock',
|
||||
'activity',
|
||||
'photos',
|
||||
'digitalClock',
|
||||
];
|
||||
|
@@ -1,14 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
<mk-container :show-header="!props.compact">
|
||||
<template #header><fa :icon="faStickyNote"/>{{ $t('_widgets.memo') }}</template>
|
||||
<mk-container :show-header="props.showHeader">
|
||||
<template #header><fa :icon="faStickyNote"/>{{ $t('_widgets.memo') }}</template>
|
||||
|
||||
<div class="otgbylcu">
|
||||
<textarea v-model="text" :placeholder="$t('placeholder')" @input="onChange"></textarea>
|
||||
<button @click="saveMemo" :disabled="!changed" class="_buttonPrimary">{{ $t('save') }}</button>
|
||||
</div>
|
||||
</mk-container>
|
||||
</div>
|
||||
<div class="otgbylcu">
|
||||
<textarea v-model="text" :placeholder="$t('placeholder')" @input="onChange"></textarea>
|
||||
<button @click="saveMemo" :disabled="!changed" class="_buttonPrimary">{{ $t('save') }}</button>
|
||||
</div>
|
||||
</mk-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -19,10 +17,12 @@ import define from './define';
|
||||
export default define({
|
||||
name: 'memo',
|
||||
props: () => ({
|
||||
compact: false
|
||||
showHeader: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
}).extend({
|
||||
|
||||
components: {
|
||||
MkContainer
|
||||
},
|
||||
@@ -45,11 +45,6 @@ export default define({
|
||||
},
|
||||
|
||||
methods: {
|
||||
func() {
|
||||
this.props.compact = !this.props.compact;
|
||||
this.save();
|
||||
},
|
||||
|
||||
onChange() {
|
||||
this.changed = true;
|
||||
clearTimeout(this.timeoutId);
|
||||
|
@@ -1,13 +1,11 @@
|
||||
<template>
|
||||
<div class="mkw-notifications" :style="`flex-basis: calc(${basis}% - var(--margin)); height: ${previewHeight}px;`">
|
||||
<mk-container :show-header="!props.compact" class="container">
|
||||
<template #header><fa :icon="faBell"/>{{ $t('notifications') }}</template>
|
||||
<mk-container :style="`height: ${props.height}px;`" :show-header="props.showHeader" :scrollable="true">
|
||||
<template #header><fa :icon="faBell"/>{{ $t('notifications') }}</template>
|
||||
|
||||
<div>
|
||||
<x-notifications/>
|
||||
</div>
|
||||
</mk-container>
|
||||
</div>
|
||||
<div>
|
||||
<x-notifications/>
|
||||
</div>
|
||||
</mk-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -16,17 +14,19 @@ import MkContainer from '../components/ui/container.vue';
|
||||
import XNotifications from '../components/notifications.vue';
|
||||
import define from './define';
|
||||
|
||||
const basisSteps = [25, 50, 75, 100]
|
||||
const previewHeights = [200, 300, 400, 500]
|
||||
|
||||
export default define({
|
||||
name: 'notifications',
|
||||
props: () => ({
|
||||
compact: false,
|
||||
basisStep: 0
|
||||
showHeader: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
height: {
|
||||
type: 'number',
|
||||
default: 300,
|
||||
},
|
||||
})
|
||||
}).extend({
|
||||
|
||||
components: {
|
||||
MkContainer,
|
||||
XNotifications,
|
||||
@@ -37,47 +37,5 @@ export default define({
|
||||
faBell
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
basis(): number {
|
||||
return basisSteps[this.props.basisStep] || 25
|
||||
},
|
||||
|
||||
previewHeight(): number {
|
||||
return previewHeights[this.props.basisStep] || 200
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
func() {
|
||||
if (this.props.basisStep === basisSteps.length - 1) {
|
||||
this.props.basisStep = 0
|
||||
this.props.compact = !this.props.compact;
|
||||
} else {
|
||||
this.props.basisStep += 1
|
||||
}
|
||||
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.mkw-notifications {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 0;
|
||||
min-height: 0; // https://www.gwtcenter.com/min-height-required-on-firefox-flexbox
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
> div {
|
||||
overflow: auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,19 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<mk-container :show-header="props.design === 0" :naked="props.design === 2" :class="$style.root" :data-melt="props.design === 2">
|
||||
<template #header><fa :icon="faCamera"/>{{ $t('_widgets.photos') }}</template>
|
||||
<mk-container :show-header="props.showHeader" :naked="props.transparent" :class="$style.root" :data-transparent="props.transparent">
|
||||
<template #header><fa :icon="faCamera"/>{{ $t('_widgets.photos') }}</template>
|
||||
|
||||
<div class="">
|
||||
<mk-loading v-if="fetching"/>
|
||||
<div v-else :class="$style.stream">
|
||||
<div v-for="(image, i) in images" :key="i"
|
||||
:class="$style.img"
|
||||
:style="`background-image: url(${thumbnail(image)})`"
|
||||
></div>
|
||||
</div>
|
||||
<div class="">
|
||||
<mk-loading v-if="fetching"/>
|
||||
<div v-else :class="$style.stream">
|
||||
<div v-for="(image, i) in images" :key="i"
|
||||
:class="$style.img"
|
||||
:style="`background-image: url(${thumbnail(image)})`"
|
||||
></div>
|
||||
</div>
|
||||
</mk-container>
|
||||
</div>
|
||||
</div>
|
||||
</mk-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -25,7 +23,14 @@ import { getStaticImageUrl } from '../scripts/get-static-image-url';
|
||||
export default define({
|
||||
name: 'photos',
|
||||
props: () => ({
|
||||
design: 0,
|
||||
showHeader: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
transparent: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
}).extend({
|
||||
components: {
|
||||
@@ -63,15 +68,6 @@ export default define({
|
||||
}
|
||||
},
|
||||
|
||||
func() {
|
||||
if (this.props.design === 2) {
|
||||
this.props.design = 0;
|
||||
} else {
|
||||
this.props.design++;
|
||||
}
|
||||
this.save();
|
||||
},
|
||||
|
||||
thumbnail(image: any): string {
|
||||
return this.$store.state.device.disableShowingAnimatedImages
|
||||
? getStaticImageUrl(image.thumbnailUrl)
|
||||
@@ -82,7 +78,7 @@ export default define({
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.root[data-melt] {
|
||||
.root[data-transparent] {
|
||||
.stream {
|
||||
padding: 0;
|
||||
}
|
||||
|
@@ -1,17 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
<mk-container :show-header="!props.compact">
|
||||
<template #header><fa :icon="faRssSquare"/>RSS</template>
|
||||
<template #func><button class="_button" @click="setting"><fa :icon="faCog"/></button></template>
|
||||
<mk-container :show-header="props.showHeader">
|
||||
<template #header><fa :icon="faRssSquare"/>RSS</template>
|
||||
<template #func><button class="_button" @click="setting"><fa :icon="faCog"/></button></template>
|
||||
|
||||
<div class="ekmkgxbj">
|
||||
<mk-loading v-if="fetching"/>
|
||||
<div class="feed" v-else>
|
||||
<a v-for="item in items" :href="item.link" rel="nofollow noopener" target="_blank" :title="item.title">{{ item.title }}</a>
|
||||
</div>
|
||||
<div class="ekmkgxbj">
|
||||
<mk-loading v-if="fetching"/>
|
||||
<div class="feed" v-else>
|
||||
<a v-for="item in items" :href="item.link" rel="nofollow noopener" target="_blank" :title="item.title">{{ item.title }}</a>
|
||||
</div>
|
||||
</mk-container>
|
||||
</div>
|
||||
</div>
|
||||
</mk-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -22,8 +20,14 @@ import define from './define';
|
||||
export default define({
|
||||
name: 'rss',
|
||||
props: () => ({
|
||||
compact: false,
|
||||
url: 'http://feeds.afpbb.com/rss/afpbb/afpbbnews'
|
||||
showHeader: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
default: 'http://feeds.afpbb.com/rss/afpbb/afpbbnews',
|
||||
},
|
||||
})
|
||||
}).extend({
|
||||
components: {
|
||||
@@ -40,15 +44,12 @@ export default define({
|
||||
mounted() {
|
||||
this.fetch();
|
||||
this.clock = setInterval(this.fetch, 60000);
|
||||
this.$watch('props.url', this.fetch);
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.clock);
|
||||
},
|
||||
methods: {
|
||||
func() {
|
||||
this.props.compact = !this.props.compact;
|
||||
this.save();
|
||||
},
|
||||
fetch() {
|
||||
fetch(`https://api.rss2json.com/v1/api.json?rss_url=${this.props.url}`, {
|
||||
}).then(res => {
|
||||
@@ -58,20 +59,6 @@ export default define({
|
||||
});
|
||||
});
|
||||
},
|
||||
setting() {
|
||||
this.$root.dialog({
|
||||
title: 'URL',
|
||||
input: {
|
||||
type: 'url',
|
||||
default: this.props.url
|
||||
}
|
||||
}).then(({ canceled, result: url }) => {
|
||||
if (canceled) return;
|
||||
this.props.url = url;
|
||||
this.save();
|
||||
this.fetch();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@@ -1,24 +1,22 @@
|
||||
<template>
|
||||
<div class="mkw-timeline" :style="`flex-basis: calc(${basis}% - var(--margin)); height: ${previewHeight}px;`">
|
||||
<mk-container :show-header="!props.compact" class="container">
|
||||
<template #header>
|
||||
<button @click="choose" class="_button">
|
||||
<fa v-if="props.src === 'home'" :icon="faHome"/>
|
||||
<fa v-if="props.src === 'local'" :icon="faComments"/>
|
||||
<fa v-if="props.src === 'social'" :icon="faShareAlt"/>
|
||||
<fa v-if="props.src === 'global'" :icon="faGlobe"/>
|
||||
<fa v-if="props.src === 'list'" :icon="faListUl"/>
|
||||
<fa v-if="props.src === 'antenna'" :icon="faSatellite"/>
|
||||
<span style="margin-left: 8px;">{{ props.src === 'list' ? props.list.name : props.src === 'antenna' ? props.antenna.name : $t('_timelines.' + props.src) }}</span>
|
||||
<fa :icon="menuOpened ? faAngleUp : faAngleDown" style="margin-left: 8px;"/>
|
||||
</button>
|
||||
</template>
|
||||
<mk-container :show-header="props.showHeader" :style="`height: ${props.height}px;`" :scrollable="true">
|
||||
<template #header>
|
||||
<button @click="choose" class="_button">
|
||||
<fa v-if="props.src === 'home'" :icon="faHome"/>
|
||||
<fa v-if="props.src === 'local'" :icon="faComments"/>
|
||||
<fa v-if="props.src === 'social'" :icon="faShareAlt"/>
|
||||
<fa v-if="props.src === 'global'" :icon="faGlobe"/>
|
||||
<fa v-if="props.src === 'list'" :icon="faListUl"/>
|
||||
<fa v-if="props.src === 'antenna'" :icon="faSatellite"/>
|
||||
<span style="margin-left: 8px;">{{ props.src === 'list' ? props.list.name : props.src === 'antenna' ? props.antenna.name : $t('_timelines.' + props.src) }}</span>
|
||||
<fa :icon="menuOpened ? faAngleUp : faAngleDown" style="margin-left: 8px;"/>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<div>
|
||||
<x-timeline :key="props.src === 'list' ? `list:${props.list.id}` : props.src === 'antenna' ? `antenna:${props.antenna.id}` : props.src" :src="props.src" :list="props.list" :antenna="props.antenna"/>
|
||||
</div>
|
||||
</mk-container>
|
||||
</div>
|
||||
<div>
|
||||
<x-timeline :key="props.src === 'list' ? `list:${props.list.id}` : props.src === 'antenna' ? `antenna:${props.antenna.id}` : props.src" :src="props.src" :list="props.list ? props.list.id : null" :antenna="props.antenna ? props.antenna.id : null"/>
|
||||
</div>
|
||||
</mk-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -28,19 +26,25 @@ import MkContainer from '../components/ui/container.vue';
|
||||
import XTimeline from '../components/timeline.vue';
|
||||
import define from './define';
|
||||
|
||||
const basisSteps = [25, 50, 75, 100]
|
||||
const previewHeights = [200, 300, 400, 500]
|
||||
|
||||
export default define({
|
||||
name: 'timeline',
|
||||
props: () => ({
|
||||
src: 'home',
|
||||
list: null,
|
||||
compact: false,
|
||||
basisStep: 0
|
||||
showHeader: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
src: {
|
||||
type: 'string',
|
||||
default: 'home',
|
||||
hidden: true,
|
||||
},
|
||||
list: {
|
||||
type: 'object',
|
||||
default: null,
|
||||
hidden: true,
|
||||
},
|
||||
})
|
||||
}).extend({
|
||||
|
||||
components: {
|
||||
MkContainer,
|
||||
XTimeline,
|
||||
@@ -53,28 +57,7 @@ export default define({
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
basis(): number {
|
||||
return basisSteps[this.props.basisStep] || 25
|
||||
},
|
||||
|
||||
previewHeight(): number {
|
||||
return previewHeights[this.props.basisStep] || 200
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
func() {
|
||||
if (this.props.basisStep === basisSteps.length - 1) {
|
||||
this.props.basisStep = 0
|
||||
this.props.compact = !this.props.compact;
|
||||
} else {
|
||||
this.props.basisStep += 1
|
||||
}
|
||||
|
||||
this.save();
|
||||
},
|
||||
|
||||
async choose(ev) {
|
||||
this.menuOpened = true;
|
||||
const [antennas, lists] = await Promise.all([
|
||||
@@ -129,22 +112,3 @@ export default define({
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.mkw-timeline {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 0;
|
||||
min-height: 0; // https://www.gwtcenter.com/min-height-required-on-firefox-flexbox
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
> div {
|
||||
overflow: auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,22 +1,20 @@
|
||||
<template>
|
||||
<div>
|
||||
<mk-container :show-header="!props.compact">
|
||||
<template #header><fa :icon="faHashtag"/>{{ $t('_widgets.trends') }}</template>
|
||||
<mk-container :show-header="props.showHeader">
|
||||
<template #header><fa :icon="faHashtag"/>{{ $t('_widgets.trends') }}</template>
|
||||
|
||||
<div class="wbrkwala">
|
||||
<mk-loading v-if="fetching"/>
|
||||
<transition-group tag="div" name="chart" class="tags" v-else>
|
||||
<div v-for="stat in stats" :key="stat.tag">
|
||||
<div class="tag">
|
||||
<router-link class="a" :to="`/tags/${ encodeURIComponent(stat.tag) }`" :title="stat.tag">#{{ stat.tag }}</router-link>
|
||||
<p>{{ $t('nUsersMentioned', { n: stat.usersCount }) }}</p>
|
||||
</div>
|
||||
<x-chart class="chart" :src="stat.chart"/>
|
||||
<div class="wbrkwala">
|
||||
<mk-loading v-if="fetching"/>
|
||||
<transition-group tag="div" name="chart" class="tags" v-else>
|
||||
<div v-for="stat in stats" :key="stat.tag">
|
||||
<div class="tag">
|
||||
<router-link class="a" :to="`/tags/${ encodeURIComponent(stat.tag) }`" :title="stat.tag">#{{ stat.tag }}</router-link>
|
||||
<p>{{ $t('nUsersMentioned', { n: stat.usersCount }) }}</p>
|
||||
</div>
|
||||
</transition-group>
|
||||
</div>
|
||||
</mk-container>
|
||||
</div>
|
||||
<x-chart class="chart" :src="stat.chart"/>
|
||||
</div>
|
||||
</transition-group>
|
||||
</div>
|
||||
</mk-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -28,7 +26,10 @@ import XChart from './trends.chart.vue';
|
||||
export default define({
|
||||
name: 'hashtags',
|
||||
props: () => ({
|
||||
compact: false
|
||||
showHeader: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
}).extend({
|
||||
components: {
|
||||
@@ -49,10 +50,6 @@ export default define({
|
||||
clearInterval(this.clock);
|
||||
},
|
||||
methods: {
|
||||
func() {
|
||||
this.props.compact = !this.props.compact;
|
||||
this.save();
|
||||
},
|
||||
fetch() {
|
||||
this.$root.api('hashtags/trend').then(stats => {
|
||||
this.stats = stats;
|
||||
|
Reference in New Issue
Block a user