wip
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs">
|
||||
<header :class="{ indicate }">
|
||||
<slot name="header"></slot>
|
||||
<button ref="menu" @click="menu">%fa:caret-down%</button>
|
||||
</header>
|
||||
<div ref="body">
|
||||
<slot></slot>
|
||||
@@ -11,8 +12,16 @@
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import Menu from '../../../../common/views/components/menu.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
indicate: false
|
||||
@@ -48,6 +57,29 @@ export default Vue.extend({
|
||||
const current = this.$refs.body.scrollTop + this.$refs.body.clientHeight;
|
||||
if (current > this.$refs.body.scrollHeight - 1) this.$emit('bottom');
|
||||
}
|
||||
},
|
||||
|
||||
menu() {
|
||||
this.os.new(Menu, {
|
||||
source: this.$refs.menu,
|
||||
compact: false,
|
||||
items: [{
|
||||
content: '%fa:arrow-left% %i18n:@swap-left%',
|
||||
onClick: () => {
|
||||
this.$store.dispatch('settings/swapLeftDeckColumn', this.id);
|
||||
}
|
||||
}, {
|
||||
content: '%fa:arrow-right% %i18n:@swap-right%',
|
||||
onClick: () => {
|
||||
this.$store.dispatch('settings/swapRightDeckColumn', this.id);
|
||||
}
|
||||
}, {
|
||||
content: '%fa:trash-alt R% %i18n:@remove%',
|
||||
onClick: () => {
|
||||
this.$store.dispatch('settings/removeDeckColumn', this.id);
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -57,6 +89,8 @@ export default Vue.extend({
|
||||
@import '~const.styl'
|
||||
|
||||
root(isDark)
|
||||
$header-height = 42px
|
||||
|
||||
flex 1
|
||||
min-width 330px
|
||||
max-width 330px
|
||||
@@ -68,7 +102,7 @@ root(isDark)
|
||||
|
||||
> header
|
||||
z-index 1
|
||||
line-height 42px
|
||||
line-height $header-height
|
||||
padding 0 16px
|
||||
color isDark ? #e3e5e8 : #888
|
||||
background isDark ? #313543 : #fff
|
||||
@@ -77,8 +111,26 @@ root(isDark)
|
||||
&.indicate
|
||||
box-shadow 0 3px 0 0 $theme-color
|
||||
|
||||
> span
|
||||
[data-fa]
|
||||
margin-right 8px
|
||||
|
||||
> button
|
||||
position absolute
|
||||
top 0
|
||||
right 0
|
||||
width $header-height
|
||||
line-height $header-height
|
||||
color isDark ? #9baec8 : #ccc
|
||||
|
||||
&:hover
|
||||
color isDark ? #b2c1d5 : #aaa
|
||||
|
||||
&:active
|
||||
color isDark ? #b2c1d5 : #999
|
||||
|
||||
> div
|
||||
height calc(100% - 42px)
|
||||
height calc(100% - $header-height)
|
||||
overflow auto
|
||||
overflow-x hidden
|
||||
|
||||
|
103
src/client/app/desktop/views/pages/deck/deck.list-tl.vue
Normal file
103
src/client/app/desktop/views/pages/deck/deck.list-tl.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<x-notes ref="timeline" :more="existMore ? more : null"/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import XNotes from './deck.notes.vue';
|
||||
import { UserListStream } from '../../../../common/scripts/streaming/user-list';
|
||||
|
||||
const fetchLimit = 10;
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
XNotes
|
||||
},
|
||||
|
||||
props: {
|
||||
list: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
fetching: true,
|
||||
moreFetching: false,
|
||||
existMore: false,
|
||||
connection: null
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.connection) this.connection.close();
|
||||
this.connection = new UserListStream((this as any).os, this.$store.state.i, this.list.id);
|
||||
this.connection.on('note', this.onNote);
|
||||
this.connection.on('userAdded', this.onUserAdded);
|
||||
this.connection.on('userRemoved', this.onUserRemoved);
|
||||
|
||||
this.fetch();
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.connection.close();
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetch() {
|
||||
this.fetching = true;
|
||||
|
||||
(this.$refs.timeline as any).init(() => new Promise((res, rej) => {
|
||||
(this as any).api('notes/user-list-timeline', {
|
||||
listId: this.list.id,
|
||||
limit: fetchLimit + 1,
|
||||
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
||||
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes
|
||||
}).then(notes => {
|
||||
if (notes.length == fetchLimit + 1) {
|
||||
notes.pop();
|
||||
this.existMore = true;
|
||||
}
|
||||
res(notes);
|
||||
this.fetching = false;
|
||||
this.$emit('loaded');
|
||||
}, rej);
|
||||
}));
|
||||
},
|
||||
more() {
|
||||
this.moreFetching = true;
|
||||
|
||||
const promise = (this as any).api('notes/user-list-timeline', {
|
||||
listId: this.list.id,
|
||||
limit: fetchLimit + 1,
|
||||
untilId: (this.$refs.timeline as any).tail().id,
|
||||
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
||||
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes
|
||||
});
|
||||
|
||||
promise.then(notes => {
|
||||
if (notes.length == fetchLimit + 1) {
|
||||
notes.pop();
|
||||
} else {
|
||||
this.existMore = false;
|
||||
}
|
||||
notes.forEach(n => (this.$refs.timeline as any).append(n));
|
||||
this.moreFetching = false;
|
||||
});
|
||||
|
||||
return promise;
|
||||
},
|
||||
onNote(note) {
|
||||
// Prepend a note
|
||||
(this.$refs.timeline as any).prepend(note);
|
||||
},
|
||||
onUserAdded() {
|
||||
this.fetch();
|
||||
},
|
||||
onUserRemoved() {
|
||||
this.fetch();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<x-column>
|
||||
<x-column :id="id">
|
||||
<span slot="header">%fa:bell R% %i18n:@notifications%</span>
|
||||
|
||||
<x-notifications/>
|
||||
@@ -17,6 +17,13 @@ export default Vue.extend({
|
||||
components: {
|
||||
XColumn,
|
||||
XNotifications
|
||||
},
|
||||
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@@ -1,13 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
<x-column>
|
||||
<x-column :id="column.id">
|
||||
<span slot="header">
|
||||
<template v-if="src == 'home'">%fa:home% %i18n:@home%</template>
|
||||
<template v-if="src == 'local'">%fa:R comments% %i18n:@local%</template>
|
||||
<template v-if="src == 'global'">%fa:globe% %i18n:@global%</template>
|
||||
<template v-if="src == 'list'">%fa:list% {{ list.title }}</template>
|
||||
<template v-if="column.type == 'home'">%fa:home%%i18n:@home%</template>
|
||||
<template v-if="column.type == 'local'">%fa:R comments%%i18n:@local%</template>
|
||||
<template v-if="column.type == 'global'">%fa:globe%%i18n:@global%</template>
|
||||
<template v-if="column.type == 'list'">%fa:list%{{ column.list.title }}</template>
|
||||
</span>
|
||||
<x-tl :src="src"/>
|
||||
|
||||
<x-list-tl v-if="column.type == 'list'" :list="column.list"/>
|
||||
<x-tl v-else :src="column.type"/>
|
||||
</x-column>
|
||||
</div>
|
||||
</template>
|
||||
@@ -16,18 +18,20 @@
|
||||
import Vue from 'vue';
|
||||
import XColumn from './deck.column.vue';
|
||||
import XTl from './deck.tl.vue';
|
||||
import XListTl from './deck.list-tl.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
XColumn,
|
||||
XTl
|
||||
XTl,
|
||||
XListTl
|
||||
},
|
||||
|
||||
props: {
|
||||
src: {
|
||||
type: String,
|
||||
required: false
|
||||
column: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@@ -27,9 +27,7 @@ export default Vue.extend({
|
||||
moreFetching: false,
|
||||
existMore: false,
|
||||
connection: null,
|
||||
connectionId: null,
|
||||
unreadCount: 0,
|
||||
date: null
|
||||
connectionId: null
|
||||
};
|
||||
},
|
||||
|
||||
@@ -74,17 +72,12 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
methods: {
|
||||
mount(root) {
|
||||
this.$refs.timeline.mount(root);
|
||||
},
|
||||
|
||||
fetch() {
|
||||
this.fetching = true;
|
||||
|
||||
(this.$refs.timeline as any).init(() => new Promise((res, rej) => {
|
||||
(this as any).api(this.endpoint, {
|
||||
limit: fetchLimit + 1,
|
||||
untilDate: this.date ? this.date.getTime() : undefined,
|
||||
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
||||
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes
|
||||
}).then(notes => {
|
||||
|
@@ -2,12 +2,13 @@
|
||||
<mk-ui :class="$style.root">
|
||||
<div class="qlvquzbjribqcaozciifydkngcwtyzje" :data-darkmode="$store.state.device.darkmode">
|
||||
<template v-for="column in columns">
|
||||
<x-notifications-column v-if="column.type == 'notifications'" :key="column.id"/>
|
||||
<x-tl-column v-if="column.type == 'home'" :key="column.id" src="home"/>
|
||||
<x-tl-column v-if="column.type == 'local'" :key="column.id" src="local"/>
|
||||
<x-tl-column v-if="column.type == 'global'" :key="column.id" src="global"/>
|
||||
<x-notifications-column v-if="column.type == 'notifications'" :key="column.id" :id="column.id"/>
|
||||
<x-tl-column v-if="column.type == 'home'" :key="column.id" :column="column"/>
|
||||
<x-tl-column v-if="column.type == 'local'" :key="column.id" :column="column"/>
|
||||
<x-tl-column v-if="column.type == 'global'" :key="column.id" :column="column"/>
|
||||
<x-tl-column v-if="column.type == 'list'" :key="column.id" :column="column"/>
|
||||
</template>
|
||||
<button>%fa:plus%</button>
|
||||
<button ref="add" @click="add">%fa:plus%</button>
|
||||
</div>
|
||||
</mk-ui>
|
||||
</template>
|
||||
@@ -16,6 +17,8 @@
|
||||
import Vue from 'vue';
|
||||
import XTlColumn from './deck.tl-column.vue';
|
||||
import XNotificationsColumn from './deck.notifications-column.vue';
|
||||
import Menu from '../../../../common/views/components/menu.vue';
|
||||
import MkUserListsWindow from '../../components/user-lists-window.vue';
|
||||
import * as uuid from 'uuid';
|
||||
|
||||
export default Vue.extend({
|
||||
@@ -55,6 +58,61 @@ export default Vue.extend({
|
||||
value: deck
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
add() {
|
||||
this.os.new(Menu, {
|
||||
source: this.$refs.add,
|
||||
compact: true,
|
||||
items: [{
|
||||
content: '%i18n:@home%',
|
||||
onClick: () => {
|
||||
this.$store.dispatch('settings/addDeckColumn', {
|
||||
id: uuid(),
|
||||
type: 'home'
|
||||
});
|
||||
}
|
||||
}, {
|
||||
content: '%i18n:@local%',
|
||||
onClick: () => {
|
||||
this.$store.dispatch('settings/addDeckColumn', {
|
||||
id: uuid(),
|
||||
type: 'local'
|
||||
});
|
||||
}
|
||||
}, {
|
||||
content: '%i18n:@global%',
|
||||
onClick: () => {
|
||||
this.$store.dispatch('settings/addDeckColumn', {
|
||||
id: uuid(),
|
||||
type: 'global'
|
||||
});
|
||||
}
|
||||
}, {
|
||||
content: '%i18n:@list%',
|
||||
onClick: () => {
|
||||
const w = (this as any).os.new(MkUserListsWindow);
|
||||
w.$once('choosen', list => {
|
||||
this.$store.dispatch('settings/addDeckColumn', {
|
||||
id: uuid(),
|
||||
type: 'list',
|
||||
list: list
|
||||
});
|
||||
w.close();
|
||||
});
|
||||
}
|
||||
}, {
|
||||
content: '%i18n:@notifications%',
|
||||
onClick: () => {
|
||||
this.$store.dispatch('settings/addDeckColumn', {
|
||||
id: uuid(),
|
||||
type: 'notifications'
|
||||
});
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
Reference in New Issue
Block a user