Skip to content
Snippets Groups Projects
Commit ca604692 authored by syuilo's avatar syuilo
Browse files

wip

parent b47fd295
No related branches found
No related tags found
No related merge requests found
Showing
with 716 additions and 496 deletions
......@@ -2,7 +2,7 @@ import Vue from 'vue';
export default function<T extends object>(data: {
name: string;
props: T;
props?: T;
}) {
return Vue.extend({
props: {
......@@ -26,7 +26,7 @@ export default function<T extends object>(data: {
},
data() {
return {
props: data.props
props: data.props || {}
};
},
watch: {
......
<template>
<div class="mkw-calendar"
:data-melt="props.design == 1"
:data-special="special"
>
<div class="calendar" :data-is-holiday="isHoliday">
<p class="month-and-year">
<span class="year">{{ year }}</span>
<span class="month">{{ month }}</span>
</p>
<p class="day">{{ day }}</p>
<p class="week-day">{{ weekDay }}曜日</p>
</div>
<div class="info">
<div>
<p>今日:<b>{{ dayP.toFixed(1) }}%</b></p>
<div class="meter">
<div class="val" :style="{ width: `${dayP}%` }"></div>
</div>
</div>
<div>
<p>今月:<b>{{ monthP.toFixed(1) }}%</b></p>
<div class="meter">
<div class="val" :style="{ width: `${monthP}%` }"></div>
</div>
</div>
<div>
<p>今年:<b>{{ yearP.toFixed(1) }}%</b></p>
<div class="meter">
<div class="val" :style="{ width: `${yearP}%` }"></div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import define from '../../../define-widget';
export default define({
name: 'calendar',
props: {
design: 0
}
}).extend({
data() {
return {
now: new Date(),
year: null,
month: null,
day: null,
weekDay: null,
yearP: null,
dayP: null,
monthP: null,
isHoliday: null,
special: null,
clock: null
};
},
created() {
this.tick();
this.clock = setInterval(this.tick, 1000);
},
beforeDestroy() {
clearInterval(this.clock);
},
methods: {
func() {
if (this.props.design == 2) {
this.props.design = 0;
} else {
this.props.design++;
}
},
tick() {
const now = new Date();
const nd = now.getDate();
const nm = now.getMonth();
const ny = now.getFullYear();
this.year = ny;
this.month = nm + 1;
this.day = nd;
this.weekDay = ['', '', '', '', '', '', ''][now.getDay()];
const dayNumer = now.getTime() - new Date(ny, nm, nd).getTime();
const dayDenom = 1000/*ms*/ * 60/*s*/ * 60/*m*/ * 24/*h*/;
const monthNumer = now.getTime() - new Date(ny, nm, 1).getTime();
const monthDenom = new Date(ny, nm + 1, 1).getTime() - new Date(ny, nm, 1).getTime();
const yearNumer = now.getTime() - new Date(ny, 0, 1).getTime();
const yearDenom = new Date(ny + 1, 0, 1).getTime() - new Date(ny, 0, 1).getTime();
this.dayP = dayNumer / dayDenom * 100;
this.monthP = monthNumer / monthDenom * 100;
this.yearP = yearNumer / yearDenom * 100;
this.isHoliday = now.getDay() == 0 || now.getDay() == 6;
this.special =
nm == 0 && nd == 1 ? 'on-new-years-day' :
false;
}
}
});
</script>
<style lang="stylus" scoped>
.mkw-calendar
padding 16px 0
color #777
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
&[data-special='on-new-years-day']
border-color #ef95a0
&[data-melt]
background transparent
border none
&:after
content ""
display block
clear both
> .calendar
float left
width 60%
text-align center
&[data-is-holiday]
> .day
color #ef95a0
> p
margin 0
line-height 18px
font-size 14px
> span
margin 0 4px
> .day
margin 10px 0
line-height 32px
font-size 28px
> .info
display block
float left
width 40%
padding 0 16px 0 0
> div
margin-bottom 8px
&:last-child
margin-bottom 4px
> p
margin 0 0 2px 0
font-size 12px
line-height 18px
color #888
> b
margin-left 2px
> .meter
width 100%
overflow hidden
background #eee
border-radius 8px
> .val
height 4px
background $theme-color
&:nth-child(1)
> .meter > .val
background #f7796c
&:nth-child(2)
> .meter > .val
background #a1de41
&:nth-child(3)
> .meter > .val
background #41ddde
</style>
<template>
<div class="mkw-donation">
<article>
<h1>%fa:heart%%i18n:desktop.tags.mk-donation-home-widget.title%</h1>
<p>
{{ '%i18n:desktop.tags.mk-donation-home-widget.text%'.substr(0, '%i18n:desktop.tags.mk-donation-home-widget.text%'.indexOf('{')) }}
<a href="/syuilo" data-user-preview="@syuilo">@syuilo</a>
{{ '%i18n:desktop.tags.mk-donation-home-widget.text%'.substr('%i18n:desktop.tags.mk-donation-home-widget.text%'.indexOf('}') + 1) }}
</p>
</article>
</div>
</template>
<script lang="ts">
import define from '../../../define-widget';
export default define({
name: 'donation'
});
</script>
<style lang="stylus" scoped>
.mkw-donation
background #fff
border solid 1px #ead8bb
border-radius 6px
> article
padding 20px
> h1
margin 0 0 5px 0
font-size 1em
color #888
> [data-fa]
margin-right 0.25em
> p
display block
z-index 1
margin 0
font-size 0.8em
color #999
</style>
<template>
<div class="mkw-messaging">
<p class="title" v-if="props.design == 0">%fa:comments%%i18n:desktop.tags.mk-messaging-home-widget.title%</p>
<mk-messaging ref="index" compact @navigate="navigate"/>
</div>
</template>
<script lang="ts">
import define from '../../../define-widget';
export default define({
name: 'messaging',
props: {
design: 0
}
}).extend({
methods: {
navigate(user) {
if (this.platform == 'desktop') {
this.wapi_openMessagingRoomWindow(user);
} else {
// TODO: open room page in new tab
}
},
func() {
if (this.props.design == 1) {
this.props.design = 0;
} else {
this.props.design++;
}
}
}
});
</script>
<style lang="stylus" scoped>
.mkw-messaging
overflow hidden
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
> .title
z-index 2
margin 0
padding 0 16px
line-height 42px
font-size 0.9em
font-weight bold
color #888
box-shadow 0 1px rgba(0, 0, 0, 0.07)
> [data-fa]
margin-right 4px
> mk-messaging
max-height 250px
overflow auto
</style>
<template>
<div class="mkw-nav">
<mk-nav-links/>
</div>
</template>
<script lang="ts">
import define from '../../../define-widget';
export default define({
name: 'nav'
});
</script>
<style lang="stylus" scoped>
.mkw-nav
padding 16px
font-size 12px
color #aaa
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
a
color #999
i
color #ccc
</style>
<template>
<div class="mkw-photo-stream" :data-melt="props.design == 2">
<p class="title" v-if="props.design == 0">%fa:camera%%i18n:desktop.tags.mk-photo-stream-home-widget.title%</p>
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
<div class="stream" v-if="!fetching && images.length > 0">
<div v-for="image in images" :key="image.id" class="img" :style="`background-image: url(${image.url}?thumbnail&size=256)`"></div>
</div>
<p class="empty" v-if="!fetching && images.length == 0">%i18n:desktop.tags.mk-photo-stream-home-widget.no-photos%</p>
</div>
</template>
<script lang="ts">
import define from '../../../define-widget';
export default define({
name: 'photo-stream',
props: {
design: 0
}
}).extend({
data() {
return {
images: [],
fetching: true,
connection: null,
connectionId: null
};
},
mounted() {
this.connection = this.$root.$data.os.stream.getConnection();
this.connectionId = this.$root.$data.os.stream.use();
this.connection.on('drive_file_created', this.onDriveFileCreated);
this.$root.$data.os.api('drive/stream', {
type: 'image/*',
limit: 9
}).then(images => {
this.fetching = false;
this.images = images;
});
},
beforeDestroy() {
this.connection.off('drive_file_created', this.onDriveFileCreated);
this.$root.$data.os.stream.dispose(this.connectionId);
},
methods: {
onStreamDriveFileCreated(file) {
if (/^image\/.+$/.test(file.type)) {
this.images.unshift(file);
if (this.images.length > 9) this.images.pop();
}
},
func() {
if (this.props.design == 2) {
this.props.design = 0;
} else {
this.props.design++;
}
}
}
});
</script>
<style lang="stylus" scoped>
.mkw-photo-stream
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
&[data-melt]
background transparent !important
border none !important
> .stream
padding 0
> .img
border solid 4px transparent
border-radius 8px
> .title
z-index 1
margin 0
padding 0 16px
line-height 42px
font-size 0.9em
font-weight bold
color #888
box-shadow 0 1px rgba(0, 0, 0, 0.07)
> [data-fa]
margin-right 4px
> .stream
display -webkit-flex
display -moz-flex
display -ms-flex
display flex
justify-content center
flex-wrap wrap
padding 8px
> .img
flex 1 1 33%
width 33%
height 80px
background-position center center
background-size cover
border solid 2px transparent
border-radius 4px
> .fetching
> .empty
margin 0
padding 16px
text-align center
color #aaa
> [data-fa]
margin-right 4px
</style>
<template>
<div class="mkw-profile"
data-compact={ data.design == 1 || data.design == 2 }
data-melt={ data.design == 2 }
:data-compact="props.design == 1 || props.design == 2"
:data-melt="props.design == 2"
>
<div class="banner"
style={ I.banner_url ? 'background-image: url(' + I.banner_url + '?thumbnail&size=256)' : '' }
......
<mk-slideshow-home-widget>
<template>
<div class="mkw-slideshow">
<div @click="choose">
<p v-if="data.folder === undefined">クリックしてフォルダを指定してください</p>
<p v-if="data.folder !== undefined && images.length == 0 && !fetching">このフォルダには画像がありません</p>
......@@ -6,102 +7,69 @@
<div ref="slideB" class="slide b"></div>
</div>
<button @click="resize">%fa:expand%</button>
<style lang="stylus" scoped>
:scope
display block
overflow hidden
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
&:hover > button
display block
> button
position absolute
left 0
bottom 0
display none
padding 4px
font-size 24px
color #fff
text-shadow 0 0 8px #000
> div
width 100%
height 100%
cursor pointer
> *
pointer-events none
> .slide
position absolute
top 0
left 0
width 100%
height 100%
background-size cover
background-position center
&.b
opacity 0
</style>
<script lang="typescript">
import * as anime from 'animejs';
this.data = {
folder: undefined,
size: 0
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import * as anime from 'animejs';
import define from '../../../define-widget';
export default define({
name: 'slideshow',
props: {
folder: undefined,
size: 0
}
}).extend({
data() {
return {
images: [],
fetching: true,
clock: null
};
this.mixin('widget');
this.images = [];
this.fetching = true;
this.on('mount', () => {
},
mounted() {
Vue.nextTick(() => {
this.applySize();
if (this.data.folder !== undefined) {
this.fetch();
}
this.clock = setInterval(this.change, 10000);
});
this.on('unmount', () => {
clearInterval(this.clock);
});
this.applySize = () => {
if (this.props.folder !== undefined) {
this.fetch();
}
this.clock = setInterval(this.change, 10000);
},
beforeDestroy() {
clearInterval(this.clock);
},
methods: {
applySize() {
let h;
if (this.data.size == 1) {
if (this.props.size == 1) {
h = 250;
} else {
h = 170;
}
this.root.style.height = `${h}px`;
};
this.resize = () => {
this.data.size++;
if (this.data.size == 2) this.data.size = 0;
this.$el.style.height = `${h}px`;
},
resize() {
if (this.props.size == 1) {
this.props.size = 0;
} else {
this.props.size++;
}
this.applySize();
this.save();
};
this.change = () => {
},
change() {
if (this.images.length == 0) return;
const index = Math.floor(Math.random() * this.images.length);
const img = `url(${ this.images[index].url }?thumbnail&size=1024)`;
this.$refs.slideB.style.backgroundImage = img;
(this.$refs.slideB as any).style.backgroundImage = img;
anime({
targets: this.$refs.slideB,
......@@ -109,7 +77,7 @@
duration: 1000,
easing: 'linear',
complete: () => {
this.$refs.slideA.style.backgroundImage = img;
(this.$refs.slideA as any).style.backgroundImage = img;
anime({
targets: this.$refs.slideB,
opacity: 0,
......@@ -117,35 +85,70 @@
});
}
});
};
this.fetch = () => {
this.update({
fetching: true
});
},
fetch() {
this.fetching = true;
this.api('drive/files', {
folder_id: this.data.folder,
this.$root.$data.os.api('drive/files', {
folder_id: this.props.folder,
type: 'image/*',
limit: 100
}).then(images => {
this.update({
fetching: false,
images: images
});
this.$refs.slideA.style.backgroundImage = '';
this.$refs.slideB.style.backgroundImage = '';
this.fetching = false;
this.images = images;
(this.$refs.slideA as any).style.backgroundImage = '';
(this.$refs.slideB as any).style.backgroundImage = '';
this.change();
});
};
this.choose = () => {
const i = riot.mount(document.body.appendChild(document.createElement('mk-select-folder-from-drive-window')))[0];
i.one('selected', folder => {
this.data.folder = folder ? folder.id : null;
},
choose() {
this.wapi_selectDriveFolder().then(folder => {
this.props.folder = folder ? folder.id : null;
this.fetch();
this.save();
});
};
</script>
</mk-slideshow-home-widget>
}
}
});
</script>
<style lang="stylus" scoped>
.mkw-slideshow
overflow hidden
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
&:hover > button
display block
> button
position absolute
left 0
bottom 0
display none
padding 4px
font-size 24px
color #fff
text-shadow 0 0 8px #000
> div
width 100%
height 100%
cursor pointer
> *
pointer-events none
> .slide
position absolute
top 0
left 0
width 100%
height 100%
background-size cover
background-position center
&.b
opacity 0
</style>
<template>
<div class="mkw-tips">
<p ref="tip">%fa:R lightbulb%<span v-html="tip"></span></p>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import * as anime from 'animejs';
import define from '../../../define-widget';
const tips = [
'<kbd>t</kbd>でタイムラインにフォーカスできます',
'<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます',
'投稿フォームにはファイルをドラッグ&ドロップできます',
'投稿フォームにクリップボードにある画像データをペーストできます',
'ドライブにファイルをドラッグ&ドロップしてアップロードできます',
'ドライブでファイルをドラッグしてフォルダ移動できます',
'ドライブでフォルダをドラッグしてフォルダ移動できます',
'ホームは設定からカスタマイズできます',
'MisskeyはMIT Licenseです',
'タイムマシンウィジェットを利用すると、簡単に過去のタイムラインに遡れます',
'投稿の ... をクリックして、投稿をユーザーページにピン留めできます',
'ドライブの容量は(デフォルトで)1GBです',
'投稿に添付したファイルは全てドライブに保存されます',
'ホームのカスタマイズ中、ウィジェットを右クリックしてデザインを変更できます',
'タイムライン上部にもウィジェットを設置できます',
'投稿をダブルクリックすると詳細が見れます',
'「**」でテキストを囲むと**強調表示**されます',
'チャンネルウィジェットを利用すると、よく利用するチャンネルを素早く確認できます',
'いくつかのウィンドウはブラウザの外に切り離すことができます',
'カレンダーウィジェットのパーセンテージは、経過の割合を示しています',
'APIを利用してbotの開発なども行えます',
'MisskeyはLINEを通じてでも利用できます',
'まゆかわいいよまゆ',
'Misskeyは2014年にサービスを開始しました',
'対応ブラウザではMisskeyを開いていなくても通知を受け取れます'
]
export default define({
name: 'tips'
}).extend({
data() {
return {
tip: null,
clock: null
};
},
mounted() {
Vue.nextTick(() => {
this.set();
});
this.clock = setInterval(this.change, 20000);
},
beforeDestroy() {
clearInterval(this.clock);
},
methods: {
set() {
this.tip = tips[Math.floor(Math.random() * tips.length)];
},
change() {
anime({
targets: this.$refs.tip,
opacity: 0,
duration: 500,
easing: 'linear',
complete: this.set
});
setTimeout(() => {
anime({
targets: this.$refs.tip,
opacity: 1,
duration: 500,
easing: 'linear'
});
}, 500);
}
}
});
</script>
<style lang="stylus" scoped>
.mkw-tips
overflow visible !important
> p
display block
margin 0
padding 0 12px
text-align center
font-size 0.7em
color #999
> [data-fa]
margin-right 4px
kbd
display inline
padding 0 6px
margin 0 2px
font-size 1em
font-family inherit
border solid 1px #999
border-radius 2px
</style>
<mk-calendar-home-widget data-melt={ data.design == 1 } data-special={ special }>
<div class="calendar" data-is-holiday={ isHoliday }>
<p class="month-and-year"><span class="year">{ year }年</span><span class="month">{ month }月</span></p>
<p class="day">{ day }日</p>
<p class="week-day">{ weekDay }曜日</p>
</div>
<div class="info">
<div>
<p>今日:<b>{ dayP.toFixed(1) }%</b></p>
<div class="meter">
<div class="val" style={ 'width:' + dayP + '%' }></div>
</div>
</div>
<div>
<p>今月:<b>{ monthP.toFixed(1) }%</b></p>
<div class="meter">
<div class="val" style={ 'width:' + monthP + '%' }></div>
</div>
</div>
<div>
<p>今年:<b>{ yearP.toFixed(1) }%</b></p>
<div class="meter">
<div class="val" style={ 'width:' + yearP + '%' }></div>
</div>
</div>
</div>
<style lang="stylus" scoped>
:scope
display block
padding 16px 0
color #777
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
&[data-special='on-new-years-day']
border-color #ef95a0
&[data-melt]
background transparent
border none
&:after
content ""
display block
clear both
> .calendar
float left
width 60%
text-align center
&[data-is-holiday]
> .day
color #ef95a0
> p
margin 0
line-height 18px
font-size 14px
> span
margin 0 4px
> .day
margin 10px 0
line-height 32px
font-size 28px
> .info
display block
float left
width 40%
padding 0 16px 0 0
> div
margin-bottom 8px
&:last-child
margin-bottom 4px
> p
margin 0 0 2px 0
font-size 12px
line-height 18px
color #888
> b
margin-left 2px
> .meter
width 100%
overflow hidden
background #eee
border-radius 8px
> .val
height 4px
background $theme-color
&:nth-child(1)
> .meter > .val
background #f7796c
&:nth-child(2)
> .meter > .val
background #a1de41
&:nth-child(3)
> .meter > .val
background #41ddde
</style>
<script lang="typescript">
this.data = {
design: 0
};
this.mixin('widget');
this.draw = () => {
const now = new Date();
const nd = now.getDate();
const nm = now.getMonth();
const ny = now.getFullYear();
this.year = ny;
this.month = nm + 1;
this.day = nd;
this.weekDay = ['日', '月', '火', '水', '木', '金', '土'][now.getDay()];
this.dayNumer = now - new Date(ny, nm, nd);
this.dayDenom = 1000/*ms*/ * 60/*s*/ * 60/*m*/ * 24/*h*/;
this.monthNumer = now - new Date(ny, nm, 1);
this.monthDenom = new Date(ny, nm + 1, 1) - new Date(ny, nm, 1);
this.yearNumer = now - new Date(ny, 0, 1);
this.yearDenom = new Date(ny + 1, 0, 1) - new Date(ny, 0, 1);
this.dayP = this.dayNumer / this.dayDenom * 100;
this.monthP = this.monthNumer / this.monthDenom * 100;
this.yearP = this.yearNumer / this.yearDenom * 100;
this.isHoliday = now.getDay() == 0 || now.getDay() == 6;
this.special =
nm == 0 && nd == 1 ? 'on-new-years-day' :
false;
this.update();
};
this.draw();
this.on('mount', () => {
this.clock = setInterval(this.draw, 1000);
});
this.on('unmount', () => {
clearInterval(this.clock);
});
this.func = () => {
if (++this.data.design == 2) this.data.design = 0;
this.save();
};
</script>
</mk-calendar-home-widget>
<mk-donation-home-widget>
<article>
<h1>%fa:heart%%i18n:desktop.tags.mk-donation-home-widget.title%</h1>
<p>{'%i18n:desktop.tags.mk-donation-home-widget.text%'.substr(0, '%i18n:desktop.tags.mk-donation-home-widget.text%'.indexOf('{'))}<a href="/syuilo" data-user-preview="@syuilo">@syuilo</a>{'%i18n:desktop.tags.mk-donation-home-widget.text%'.substr('%i18n:desktop.tags.mk-donation-home-widget.text%'.indexOf('}') + 1)}</p>
</article>
<style lang="stylus" scoped>
:scope
display block
background #fff
border solid 1px #ead8bb
border-radius 6px
> article
padding 20px
> h1
margin 0 0 5px 0
font-size 1em
color #888
> [data-fa]
margin-right 0.25em
> p
display block
z-index 1
margin 0
font-size 0.8em
color #999
</style>
<script lang="typescript">
this.mixin('widget');
this.mixin('user-preview');
</script>
</mk-donation-home-widget>
<mk-messaging-home-widget>
<template v-if="data.design == 0">
<p class="title">%fa:comments%%i18n:desktop.tags.mk-messaging-home-widget.title%</p>
</template>
<mk-messaging ref="index" compact={ true }/>
<style lang="stylus" scoped>
:scope
display block
overflow hidden
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
> .title
z-index 2
margin 0
padding 0 16px
line-height 42px
font-size 0.9em
font-weight bold
color #888
box-shadow 0 1px rgba(0, 0, 0, 0.07)
> [data-fa]
margin-right 4px
> mk-messaging
max-height 250px
overflow auto
</style>
<script lang="typescript">
this.data = {
design: 0
};
this.mixin('widget');
this.on('mount', () => {
this.$refs.index.on('navigate-user', user => {
riot.mount(document.body.appendChild(document.createElement('mk-messaging-room-window')), {
user: user
});
});
});
this.func = () => {
if (++this.data.design == 2) this.data.design = 0;
this.save();
};
</script>
</mk-messaging-home-widget>
<mk-nav-home-widget>
<mk-nav-links/>
<style lang="stylus" scoped>
:scope
display block
padding 16px
font-size 12px
color #aaa
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
a
color #999
i
color #ccc
</style>
<script lang="typescript">
this.mixin('widget');
</script>
</mk-nav-home-widget>
<mk-photo-stream-home-widget data-melt={ data.design == 2 }>
<template v-if="data.design == 0">
<p class="title">%fa:camera%%i18n:desktop.tags.mk-photo-stream-home-widget.title%</p>
</template>
<p class="initializing" v-if="initializing">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
<div class="stream" v-if="!initializing && images.length > 0">
<template each={ image in images }>
<div class="img" style={ 'background-image: url(' + image.url + '?thumbnail&size=256)' }></div>
</template>
</div>
<p class="empty" v-if="!initializing && images.length == 0">%i18n:desktop.tags.mk-photo-stream-home-widget.no-photos%</p>
<style lang="stylus" scoped>
:scope
display block
background #fff
border solid 1px rgba(0, 0, 0, 0.075)
border-radius 6px
&[data-melt]
background transparent !important
border none !important
> .stream
padding 0
> .img
border solid 4px transparent
border-radius 8px
> .title
z-index 1
margin 0
padding 0 16px
line-height 42px
font-size 0.9em
font-weight bold
color #888
box-shadow 0 1px rgba(0, 0, 0, 0.07)
> [data-fa]
margin-right 4px
> .stream
display -webkit-flex
display -moz-flex
display -ms-flex
display flex
justify-content center
flex-wrap wrap
padding 8px
> .img
flex 1 1 33%
width 33%
height 80px
background-position center center
background-size cover
border solid 2px transparent
border-radius 4px
> .initializing
> .empty
margin 0
padding 16px
text-align center
color #aaa
> [data-fa]
margin-right 4px
</style>
<script lang="typescript">
this.data = {
design: 0
};
this.mixin('widget');
this.mixin('stream');
this.connection = this.stream.getConnection();
this.connectionId = this.stream.use();
this.images = [];
this.initializing = true;
this.on('mount', () => {
this.connection.on('drive_file_created', this.onStreamDriveFileCreated);
this.api('drive/stream', {
type: 'image/*',
limit: 9
}).then(images => {
this.update({
initializing: false,
images: images
});
});
});
this.on('unmount', () => {
this.connection.off('drive_file_created', this.onStreamDriveFileCreated);
this.stream.dispose(this.connectionId);
});
this.onStreamDriveFileCreated = file => {
if (/^image\/.+$/.test(file.type)) {
this.images.unshift(file);
if (this.images.length > 9) this.images.pop();
this.update();
}
};
this.func = () => {
if (++this.data.design == 3) this.data.design = 0;
this.save();
};
</script>
</mk-photo-stream-home-widget>
<mk-tips-home-widget>
<p ref="tip">%fa:R lightbulb%<span ref="text"></span></p>
<style lang="stylus" scoped>
:scope
display block
overflow visible !important
> p
display block
margin 0
padding 0 12px
text-align center
font-size 0.7em
color #999
> [data-fa]
margin-right 4px
kbd
display inline
padding 0 6px
margin 0 2px
font-size 1em
font-family inherit
border solid 1px #999
border-radius 2px
</style>
<script lang="typescript">
import * as anime from 'animejs';
this.mixin('widget');
this.tips = [
'<kbd>t</kbd>でタイムラインにフォーカスできます',
'<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます',
'投稿フォームにはファイルをドラッグ&ドロップできます',
'投稿フォームにクリップボードにある画像データをペーストできます',
'ドライブにファイルをドラッグ&ドロップしてアップロードできます',
'ドライブでファイルをドラッグしてフォルダ移動できます',
'ドライブでフォルダをドラッグしてフォルダ移動できます',
'ホームは設定からカスタマイズできます',
'MisskeyはMIT Licenseです',
'タイムマシンウィジェットを利用すると、簡単に過去のタイムラインに遡れます',
'投稿の ... をクリックして、投稿をユーザーページにピン留めできます',
'ドライブの容量は(デフォルトで)1GBです',
'投稿に添付したファイルは全てドライブに保存されます',
'ホームのカスタマイズ中、ウィジェットを右クリックしてデザインを変更できます',
'タイムライン上部にもウィジェットを設置できます',
'投稿をダブルクリックすると詳細が見れます',
'「**」でテキストを囲むと**強調表示**されます',
'チャンネルウィジェットを利用すると、よく利用するチャンネルを素早く確認できます',
'いくつかのウィンドウはブラウザの外に切り離すことができます',
'カレンダーウィジェットのパーセンテージは、経過の割合を示しています',
'APIを利用してbotの開発なども行えます',
'MisskeyはLINEを通じてでも利用できます',
'まゆかわいいよまゆ',
'Misskeyは2014年にサービスを開始しました',
'対応ブラウザではMisskeyを開いていなくても通知を受け取れます'
]
this.on('mount', () => {
this.set();
this.clock = setInterval(this.change, 20000);
});
this.on('unmount', () => {
clearInterval(this.clock);
});
this.set = () => {
this.$refs.text.innerHTML = this.tips[Math.floor(Math.random() * this.tips.length)];
};
this.change = () => {
anime({
targets: this.$refs.tip,
opacity: 0,
duration: 500,
easing: 'linear',
complete: this.set
});
setTimeout(() => {
anime({
targets: this.$refs.tip,
opacity: 1,
duration: 500,
easing: 'linear'
});
}, 500);
};
</script>
</mk-tips-home-widget>
......@@ -11,11 +11,11 @@ const isProduction = env === 'production';
export default (version, lang) => {
const plugins = [
consts(lang),
new StringReplacePlugin(),
hoist()
new StringReplacePlugin()
];
if (isProduction) {
plugins.push(hoist());
plugins.push(minify());
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment