summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-02-19 18:26:20 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-02-19 18:26:20 +0900
commit0c9a7cf6434a5238a1b97870e04c74b75e6191f5 (patch)
treebac74cc5def740f23ab3f909fc26805983b9a0c5
parentwip (diff)
downloadmisskey-0c9a7cf6434a5238a1b97870e04c74b75e6191f5.tar.gz
misskey-0c9a7cf6434a5238a1b97870e04c74b75e6191f5.tar.bz2
misskey-0c9a7cf6434a5238a1b97870e04c74b75e6191f5.zip
wip
-rw-r--r--.eslintrc17
-rw-r--r--package.json3
-rw-r--r--src/web/app/desktop/-tags/home-widgets/timemachine.tag23
-rw-r--r--src/web/app/desktop/views/components/calendar.vue9
-rw-r--r--src/web/app/desktop/views/components/home.vue224
-rw-r--r--src/web/app/desktop/views/components/index.ts4
-rw-r--r--src/web/app/desktop/views/components/timeline.vue15
-rw-r--r--src/web/app/desktop/views/components/widgets/timemachine.vue28
8 files changed, 161 insertions, 162 deletions
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000000..d30cf2aa56
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,17 @@
+{
+ "parserOptions": {
+ "parser": "typescript-eslint-parser"
+ },
+ "extends": [
+ "eslint:recommended",
+ "plugin:vue/recommended"
+ ],
+ "rules": {
+ "vue/require-v-for-key": false,
+ "vue/max-attributes-per-line": false,
+ "vue/html-indent": false,
+ "vue/html-self-closing": false,
+ "vue/no-unused-vars": false,
+ "no-console": 0
+ }
+}
diff --git a/package.json b/package.json
index e87be0ab21..727c4af716 100644
--- a/package.json
+++ b/package.json
@@ -99,6 +99,8 @@
"diskusage": "0.2.4",
"elasticsearch": "14.1.0",
"escape-regexp": "0.0.1",
+ "eslint": "^4.18.0",
+ "eslint-plugin-vue": "^4.2.2",
"eventemitter3": "3.0.0",
"exif-js": "2.3.0",
"express": "4.16.2",
@@ -174,6 +176,7 @@
"ts-node": "4.1.0",
"tslint": "5.9.1",
"typescript": "2.7.1",
+ "typescript-eslint-parser": "^13.0.0",
"uglify-es": "3.3.9",
"uglifyjs-webpack-plugin": "1.1.8",
"uuid": "3.2.1",
diff --git a/src/web/app/desktop/-tags/home-widgets/timemachine.tag b/src/web/app/desktop/-tags/home-widgets/timemachine.tag
deleted file mode 100644
index 43f59fe674..0000000000
--- a/src/web/app/desktop/-tags/home-widgets/timemachine.tag
+++ /dev/null
@@ -1,23 +0,0 @@
-<mk-timemachine-home-widget>
- <mk-calendar-widget design={ data.design } warp={ warp }/>
- <style lang="stylus" scoped>
- :scope
- display block
- </style>
- <script lang="typescript">
- this.data = {
- design: 0
- };
-
- this.mixin('widget');
-
- this.warp = date => {
- this.opts.tl.warp(date);
- };
-
- this.func = () => {
- if (++this.data.design == 6) this.data.design = 0;
- this.save();
- };
- </script>
-</mk-timemachine-home-widget>
diff --git a/src/web/app/desktop/views/components/calendar.vue b/src/web/app/desktop/views/components/calendar.vue
index 3380774028..e548a82c57 100644
--- a/src/web/app/desktop/views/components/calendar.vue
+++ b/src/web/app/desktop/views/components/calendar.vue
@@ -7,16 +7,15 @@
</template>
<div class="calendar">
+ <template v-if="design == 0 || design == 2 || design == 4">
<div class="weekday"
- v-if="design == 0 || design == 2 || design == 4"
v-for="(day, i) in Array(7).fill(0)"
- :key="i"
:data-today="year == today.getFullYear() && month == today.getMonth() + 1 && today.getDay() == i"
:data-is-donichi="i == 0 || i == 6"
>{{ weekdayText[i] }}</div>
- <div each={ day, i in Array(paddingDays).fill(0) }></div>
- <div class="day" v-for="(day, i) in Array(days).fill(0)"
- :key="i"
+ </template>
+ <div v-for="n in paddingDays"></div>
+ <div class="day" v-for="(day, i) in days"
:data-today="isToday(i + 1)"
:data-selected="isSelected(i + 1)"
:data-is-out-of-range="isOutOfRange(i + 1)"
diff --git a/src/web/app/desktop/views/components/home.vue b/src/web/app/desktop/views/components/home.vue
index 3a04e13cb2..e815239d3f 100644
--- a/src/web/app/desktop/views/components/home.vue
+++ b/src/web/app/desktop/views/components/home.vue
@@ -37,43 +37,21 @@
</div>
</div>
<div class="main">
- <div class="left">
- <div ref="left" data-place="left">
- <template v-for="widget in leftWidgets">
+ <div v-for="place in ['left', 'main', 'right']" :class="place" :ref="place" :data-place="place">
+ <template v-if="place != 'main'">
+ <template v-for="widget in widgets[place]">
<div class="customize-container" v-if="customize" :key="widget.id" @contextmenu.stop.prevent="onWidgetContextmenu(widget.id)">
- <component :is="'mkw-' + widget.name" :widget="widget" :ref="widget.id"/>
+ <component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id"/>
</div>
<template v-else>
- <component :is="'mkw-' + widget.name" :key="widget.id" :widget="widget" :ref="widget.id"/>
+ <component :is="`mkw-${widget.name}`" :key="widget.id" :widget="widget" :ref="widget.id" @chosen="warp"/>
</template>
</template>
- </div>
- </div>
- <main ref="main">
- <div class="maintop" ref="maintop" data-place="main" v-if="customize">
- <template v-for="widget in centerWidgets">
- <div class="customize-container" v-if="customize" :key="widget.id" @contextmenu.stop.prevent="onWidgetContextmenu(widget.id)">
- <component :is="'mkw-' + widget.name" :widget="widget" :ref="widget.id"/>
- </div>
- <template v-else>
- <component :is="'mkw-' + widget.name" :key="widget.id" :widget="widget" :ref="widget.id"/>
- </template>
- </template>
- </div>
- <mk-timeline ref="tl" @loaded="onTlLoaded" v-if="mode == 'timeline'"/>
- <mk-mentions ref="tl" @loaded="onTlLoaded" v-if="mode == 'mentions'"/>
- </main>
- <div class="right">
- <div ref="right" data-place="right">
- <template v-for="widget in rightWidgets">
- <div class="customize-container" v-if="customize" :key="widget.id" @contextmenu.stop.prevent="onWidgetContextmenu(widget.id)">
- <component :is="'mkw-' + widget.name" :widget="widget" :ref="widget.id"/>
- </div>
- <template v-else>
- <component :is="'mkw-' + widget.name" :key="widget.id" :widget="widget" :ref="widget.id"/>
- </template>
- </template>
- </div>
+ </template>
+ <template v-else>
+ <mk-timeline ref="tl" @loaded="onTlLoaded" v-if="place == 'main' && mode == 'timeline'"/>
+ <mk-mentions @loaded="onTlLoaded" v-if="place == 'main' && mode == 'mentions'"/>
+ </template>
</div>
</div>
</div>
@@ -99,6 +77,85 @@ export default Vue.extend({
widgetAdderSelected: null
};
},
+ computed: {
+ leftWidgets(): any {
+ return (this as any).os.i.client_settings.home.filter(w => w.place == 'left');
+ },
+ rightWidgets(): any {
+ return (this as any).os.i.client_settings.home.filter(w => w.place == 'right');
+ },
+ widgets(): any {
+ return {
+ left: this.leftWidgets,
+ right: this.rightWidgets,
+ };
+ },
+ leftEl(): Element {
+ return (this.$refs.left as Element[])[0];
+ },
+ rightEl(): Element {
+ return (this.$refs.right as Element[])[0];
+ }
+ },
+ created() {
+ this.bakedHomeData = this.bakeHomeData();
+ },
+ mounted() {
+ (this as any).os.i.on('refreshed', this.onMeRefreshed);
+
+ this.home = (this as any).os.i.client_settings.home;
+
+ this.$nextTick(() => {
+ if (!this.customize) {
+ if (this.leftEl.children.length == 0) {
+ this.leftEl.parentNode.removeChild(this.leftEl);
+ }
+ if (this.rightEl.children.length == 0) {
+ this.rightEl.parentNode.removeChild(this.rightEl);
+ }
+ }
+
+ if (this.customize) {
+ (this as any).apis.dialog({
+ title: '%fa:info-circle%カスタマイズのヒント',
+ text: '<p>ホームのカスタマイズでは、ウィジェットを追加/削除したり、ドラッグ&ドロップして並べ替えたりすることができます。</p>' +
+ '<p>一部のウィジェットは、<strong><strong>右</strong>クリック</strong>することで表示を変更することができます。</p>' +
+ '<p>ウィジェットを削除するには、ヘッダーの<strong>「ゴミ箱」</strong>と書かれたエリアにウィジェットをドラッグ&ドロップします。</p>' +
+ '<p>カスタマイズを終了するには、右上の「完了」をクリックします。</p>',
+ actions: [{
+ text: 'Got it!'
+ }]
+ });
+
+ const sortableOption = {
+ group: 'kyoppie',
+ animation: 150,
+ onMove: evt => {
+ const id = evt.dragged.getAttribute('data-widget-id');
+ this.home.find(tag => tag.id == id).widget.place = evt.to.getAttribute('data-place');
+ },
+ onSort: () => {
+ this.saveHome();
+ }
+ };
+
+ new Sortable(this.leftEl, sortableOption);
+ new Sortable(this.rightEl, sortableOption);
+ new Sortable(this.$refs.trash, Object.assign({}, sortableOption, {
+ onAdd: evt => {
+ const el = evt.item;
+ const id = el.getAttribute('data-widget-id');
+ el.parentNode.removeChild(el);
+ (this as any).os.i.client_settings.home = (this as any).os.i.client_settings.home.filter(w => w.id != id);
+ this.saveHome();
+ }
+ }));
+ }
+ });
+ },
+ beforeDestroy() {
+ (this as any).os.i.off('refreshed', this.onMeRefreshed);
+ },
methods: {
bakeHomeData() {
return JSON.stringify((this as any).os.i.client_settings.home);
@@ -130,102 +187,27 @@ export default Vue.extend({
saveHome() {
const data = [];
- Array.from((this.$refs.left as Element).children).forEach(el => {
+ Array.from(this.leftEl.children).forEach(el => {
const id = el.getAttribute('data-widget-id');
const widget = (this as any).os.i.client_settings.home.find(w => w.id == id);
widget.place = 'left';
data.push(widget);
});
- Array.from((this.$refs.right as Element).children).forEach(el => {
+ Array.from(this.rightEl.children).forEach(el => {
const id = el.getAttribute('data-widget-id');
const widget = (this as any).os.i.client_settings.home.find(w => w.id == id);
widget.place = 'right';
data.push(widget);
});
- Array.from((this.$refs.maintop as Element).children).forEach(el => {
- const id = el.getAttribute('data-widget-id');
- const widget = (this as any).os.i.client_settings.home.find(w => w.id == id);
- widget.place = 'main';
- data.push(widget);
- });
-
(this as any).api('i/update_home', {
home: data
});
- }
- },
- computed: {
- leftWidgets(): any {
- return (this as any).os.i.client_settings.home.filter(w => w.place == 'left');
- },
- centerWidgets(): any {
- return (this as any).os.i.client_settings.home.filter(w => w.place == 'center');
},
- rightWidgets(): any {
- return (this as any).os.i.client_settings.home.filter(w => w.place == 'right');
+ warp(date) {
+ (this.$refs.tl as any)[0].warp(date);
}
- },
- created() {
- this.bakedHomeData = this.bakeHomeData();
- },
- mounted() {
- (this as any).os.i.on('refreshed', this.onMeRefreshed);
-
- this.home = (this as any).os.i.client_settings.home;
-
- if (!this.customize) {
- if ((this.$refs.left as Element).children.length == 0) {
- (this.$refs.left as Element).parentNode.removeChild((this.$refs.left as Element));
- }
- if ((this.$refs.right as Element).children.length == 0) {
- (this.$refs.right as Element).parentNode.removeChild((this.$refs.right as Element));
- }
- }
-
- if (this.customize) {
- /*dialog('%fa:info-circle%カスタマイズのヒント',
- '<p>ホームのカスタマイズでは、ウィジェットを追加/削除したり、ドラッグ&ドロップして並べ替えたりすることができます。</p>' +
- '<p>一部のウィジェットは、<strong><strong>右</strong>クリック</strong>することで表示を変更することができます。</p>' +
- '<p>ウィジェットを削除するには、ヘッダーの<strong>「ゴミ箱」</strong>と書かれたエリアにウィジェットをドラッグ&ドロップします。</p>' +
- '<p>カスタマイズを終了するには、右上の「完了」をクリックします。</p>',
- [{
- text: 'Got it!'
- }]);*/
-
- const sortableOption = {
- group: 'kyoppie',
- animation: 150,
- onMove: evt => {
- const id = evt.dragged.getAttribute('data-widget-id');
- this.home.find(tag => tag.id == id).update({ place: evt.to.getAttribute('data-place') });
- },
- onSort: () => {
- this.saveHome();
- }
- };
-
- new Sortable(this.$refs.left, sortableOption);
- new Sortable(this.$refs.right, sortableOption);
- new Sortable(this.$refs.maintop, sortableOption);
- new Sortable(this.$refs.trash, Object.assign({}, sortableOption, {
- onAdd: evt => {
- const el = evt.item;
- const id = el.getAttribute('data-widget-id');
- el.parentNode.removeChild(el);
- (this as any).os.i.client_settings.home = (this as any).os.i.client_settings.home.filter(w => w.id != id);
- this.saveHome();
- }
- }));
- }
- },
- beforeDestroy() {
- (this as any).os.i.off('refreshed', this.onMeRefreshed);
-
- this.home.forEach(widget => {
- widget.unmount();
- });
}
});
</script>
@@ -324,26 +306,16 @@ export default Vue.extend({
> *
pointer-events none
- > main
+ > .main
padding 16px
width calc(100% - 275px * 2)
- > *:not(.maintop):not(:last-child)
- > .maintop > *:not(:last-child)
- margin-bottom 16px
-
- > .maintop
- min-height 64px
- margin-bottom 16px
-
> *:not(main)
width 275px
+ padding 16px 0 16px 0
- > *
- padding 16px 0 16px 0
-
- > *:not(:last-child)
- margin-bottom 16px
+ > *:not(:last-child)
+ margin-bottom 16px
> .left
padding-left 16px
@@ -355,7 +327,7 @@ export default Vue.extend({
> *:not(main)
display none
- > main
+ > .main
float none
width 100%
max-width 700px
diff --git a/src/web/app/desktop/views/components/index.ts b/src/web/app/desktop/views/components/index.ts
index 151ebf296b..9a27369547 100644
--- a/src/web/app/desktop/views/components/index.ts
+++ b/src/web/app/desktop/views/components/index.ts
@@ -33,6 +33,7 @@ import driveFolder from './drive-folder.vue';
import driveNavFolder from './drive-nav-folder.vue';
import postDetail from './post-detail.vue';
import settings from './settings.vue';
+import calendar from './calendar.vue';
import wNav from './widgets/nav.vue';
import wCalendar from './widgets/calendar.vue';
import wPhotoStream from './widgets/photo-stream.vue';
@@ -41,6 +42,7 @@ import wTips from './widgets/tips.vue';
import wDonation from './widgets/donation.vue';
import wNotifications from './widgets/notifications.vue';
import wBroadcast from './widgets/broadcast.vue';
+import wTimemachine from './widgets/timemachine.vue';
Vue.component('mk-ui', ui);
Vue.component('mk-ui-header', uiHeader);
@@ -75,6 +77,7 @@ Vue.component('mk-drive-folder', driveFolder);
Vue.component('mk-drive-nav-folder', driveNavFolder);
Vue.component('mk-post-detail', postDetail);
Vue.component('mk-settings', settings);
+Vue.component('mk-calendar', calendar);
Vue.component('mkw-nav', wNav);
Vue.component('mkw-calendar', wCalendar);
Vue.component('mkw-photo-stream', wPhotoStream);
@@ -83,3 +86,4 @@ Vue.component('mkw-tips', wTips);
Vue.component('mkw-donation', wDonation);
Vue.component('mkw-notifications', wNotifications);
Vue.component('mkw-broadcast', wBroadcast);
+Vue.component('mkw-timemachine', wTimemachine);
diff --git a/src/web/app/desktop/views/components/timeline.vue b/src/web/app/desktop/views/components/timeline.vue
index 3d792436e0..66d70a9578 100644
--- a/src/web/app/desktop/views/components/timeline.vue
+++ b/src/web/app/desktop/views/components/timeline.vue
@@ -13,19 +13,14 @@
import Vue from 'vue';
export default Vue.extend({
- props: {
- date: {
- type: Date,
- required: false
- }
- },
data() {
return {
fetching: true,
moreFetching: false,
posts: [],
connection: null,
- connectionId: null
+ connectionId: null,
+ date: null
};
},
computed: {
@@ -60,7 +55,7 @@ export default Vue.extend({
this.fetching = true;
(this as any).api('posts/timeline', {
- until_date: this.date ? (this.date as any).getTime() : undefined
+ until_date: this.date ? this.date.getTime() : undefined
}).then(posts => {
this.fetching = false;
this.posts = posts;
@@ -93,6 +88,10 @@ export default Vue.extend({
(this.$refs.timeline as any).focus();
}
}
+ },
+ warp(date) {
+ this.date = date;
+ this.fetch();
}
}
});
diff --git a/src/web/app/desktop/views/components/widgets/timemachine.vue b/src/web/app/desktop/views/components/widgets/timemachine.vue
new file mode 100644
index 0000000000..d484ce6d74
--- /dev/null
+++ b/src/web/app/desktop/views/components/widgets/timemachine.vue
@@ -0,0 +1,28 @@
+<template>
+<div class="mkw-timemachine">
+ <mk-calendar :design="props.design" @chosen="chosen"/>
+</div>
+</template>
+
+<script lang="ts">
+import define from '../../../../common/define-widget';
+export default define({
+ name: 'timemachine',
+ props: {
+ design: 0
+ }
+}).extend({
+ methods: {
+ chosen(date) {
+ this.$emit('chosen', date);
+ },
+ func() {
+ if (this.props.design == 5) {
+ this.props.design = 0;
+ } else {
+ this.props.design++;
+ }
+ }
+ }
+});
+</script>