summaryrefslogtreecommitdiff
path: root/src/client/widgets
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2020-12-05 22:29:55 +0900
committersyuilo <syuilotan@yahoo.co.jp>2020-12-05 22:29:55 +0900
commit2112fb38963fda343dff83ea97d1f2740246fbdd (patch)
tree3ed8496a725bbad722d443af3ca9db7d13228f42 /src/client/widgets
parent12.62.0 (diff)
downloadsharkey-2112fb38963fda343dff83ea97d1f2740246fbdd.tar.gz
sharkey-2112fb38963fda343dff83ea97d1f2740246fbdd.tar.bz2
sharkey-2112fb38963fda343dff83ea97d1f2740246fbdd.zip
Add slideshow widget
Diffstat (limited to 'src/client/widgets')
-rw-r--r--src/client/widgets/index.ts2
-rw-r--r--src/client/widgets/slideshow.vue168
2 files changed, 170 insertions, 0 deletions
diff --git a/src/client/widgets/index.ts b/src/client/widgets/index.ts
index ee76bd97d2..c8bee90e4f 100644
--- a/src/client/widgets/index.ts
+++ b/src/client/widgets/index.ts
@@ -13,6 +13,7 @@ export default function(app: App) {
app.component('MkwDigitalClock', defineAsyncComponent(() => import('./digital-clock.vue')));
app.component('MkwFederation', defineAsyncComponent(() => import('./federation.vue')));
app.component('MkwPostForm', defineAsyncComponent(() => import('./post-form.vue')));
+ app.component('MkwSlideshow', defineAsyncComponent(() => import('./slideshow.vue')));
}
export const widgets = [
@@ -28,4 +29,5 @@ export const widgets = [
'digitalClock',
'federation',
'postForm',
+ 'slideshow',
];
diff --git a/src/client/widgets/slideshow.vue b/src/client/widgets/slideshow.vue
new file mode 100644
index 0000000000..0c1a2dc863
--- /dev/null
+++ b/src/client/widgets/slideshow.vue
@@ -0,0 +1,168 @@
+<template>
+<div class="kvausudm _panel">
+ <div @click="choose">
+ <p v-if="props.folderId == null">
+ <template v-if="isCustomizeMode">{{ $t('folder-customize-mode') }}</template>
+ <template v-else>{{ $t('folder') }}</template>
+ </p>
+ <p v-if="props.folderId != null && images.length === 0 && !fetching">{{ $t('no-image') }}</p>
+ <div ref="slideA" class="slide a"></div>
+ <div ref="slideB" class="slide b"></div>
+ </div>
+</div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import { } from '@fortawesome/free-solid-svg-icons';
+import define from './define';
+import * as os from '@/os';
+
+const widget = define({
+ name: 'slideshow',
+ props: () => ({
+ height: {
+ type: 'number',
+ default: 300,
+ },
+ folderId: {
+ type: 'string',
+ default: null,
+ hidden: true,
+ },
+ })
+});
+
+export default defineComponent({
+ extends: widget,
+ data() {
+ return {
+ images: [],
+ fetching: true,
+ clock: null
+ };
+ },
+ mounted() {
+ this.$nextTick(() => {
+ this.applySize();
+ });
+
+ if (this.props.folderId != null) {
+ this.fetch();
+ }
+
+ this.clock = setInterval(this.change, 10000);
+ },
+ beforeUnmount() {
+ clearInterval(this.clock);
+ },
+ methods: {
+ applySize() {
+ let h;
+
+ if (this.props.size == 1) {
+ h = 250;
+ } else {
+ h = 170;
+ }
+
+ this.$el.style.height = `${h}px`;
+ },
+ resize() {
+ if (this.props.size == 1) {
+ this.props.size = 0;
+ } else {
+ this.props.size++;
+ }
+ this.save();
+
+ this.applySize();
+ },
+ change() {
+ if (this.images.length == 0) return;
+
+ const index = Math.floor(Math.random() * this.images.length);
+ const img = `url(${ this.images[index].url })`;
+
+ (this.$refs.slideB as any).style.backgroundImage = img;
+
+ this.$refs.slideB.classList.add('anime');
+ setTimeout(() => {
+ // 既にこのウィジェットがunmountされていたら要素がない
+ if ((this.$refs.slideA as any) == null) return;
+
+ (this.$refs.slideA as any).style.backgroundImage = img;
+
+ this.$refs.slideB.classList.remove('anime');
+ }, 1000);
+ },
+ fetch() {
+ this.fetching = true;
+
+ os.api('drive/files', {
+ folderId: this.props.folderId,
+ type: 'image/*',
+ limit: 100
+ }).then(images => {
+ this.images = images;
+ this.fetching = false;
+ (this.$refs.slideA as any).style.backgroundImage = '';
+ (this.$refs.slideB as any).style.backgroundImage = '';
+ this.change();
+ });
+ },
+ choose() {
+ os.selectDriveFolder(false).then(folder => {
+ if (folder == null) {
+ return;
+ }
+ this.props.folderId = folder.id;
+ this.save();
+ this.fetch();
+ });
+ }
+ }
+});
+</script>
+
+<style lang="scss" scoped>
+.kvausudm {
+ position: relative;
+
+ > div {
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+
+ > p {
+ display: block;
+ margin: 1em;
+ text-align: center;
+ color: #888;
+ }
+
+ > * {
+ pointer-events: none;
+ }
+
+ > .slide {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-size: cover;
+ background-position: center;
+
+ &.b {
+ opacity: 0;
+ }
+
+ &.anime {
+ transition: opacity 1s;
+ opacity: 1;
+ }
+ }
+ }
+}
+</style>