summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAya Morisawa <AyaMorisawa4869@gmail.com>2019-10-29 09:51:19 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2019-10-29 09:51:19 +0900
commitbf654c6f42179612c19d70bf1970f930efc25d54 (patch)
tree309a51f55d04b3dc39ef304952e72a9a4828977a /src
parentMake issue process of registration tickets better (#5545) (diff)
downloadsharkey-bf654c6f42179612c19d70bf1970f930efc25d54.tar.gz
sharkey-bf654c6f42179612c19d70bf1970f930efc25d54.tar.bz2
sharkey-bf654c6f42179612c19d70bf1970f930efc25d54.zip
Componentize modal (#5386)
Diffstat (limited to 'src')
-rw-r--r--src/client/app/common/views/components/dialog.vue135
-rw-r--r--src/client/app/common/views/components/image-viewer.vue62
-rw-r--r--src/client/app/common/views/components/index.ts2
-rw-r--r--src/client/app/common/views/components/ui/modal.vue80
-rw-r--r--src/client/app/desktop/views/components/media-video-dialog.vue55
-rw-r--r--src/client/app/mobile/views/components/post-form-dialog.vue71
6 files changed, 185 insertions, 220 deletions
diff --git a/src/client/app/common/views/components/dialog.vue b/src/client/app/common/views/components/dialog.vue
index d5906eb4c4..2744903007 100644
--- a/src/client/app/common/views/components/dialog.vue
+++ b/src/client/app/common/views/components/dialog.vue
@@ -1,6 +1,12 @@
<template>
-<div class="felqjxyj" :class="{ splash }">
- <div class="bg" ref="bg" @click="onBgClick"></div>
+<ui-modal
+ ref="modal"
+ class="modal"
+ :class="{ splash }"
+ :close-anime-duration="300"
+ :close-on-bg-click="false"
+ @bg-click="onBgClick"
+ @before-close="onBeforeClose">
<div class="main" ref="main" :class="{ round: $store.state.device.roundedCorners }">
<template v-if="type == 'signin'">
<mk-signin/>
@@ -38,7 +44,7 @@
</ui-horizon-group>
</template>
</div>
-</div>
+</ui-modal>
</template>
<script lang="ts">
@@ -120,14 +126,6 @@ export default Vue.extend({
if (this.user) this.canOk = false;
this.$nextTick(() => {
- (this.$refs.bg as any).style.pointerEvents = 'auto';
- anime({
- targets: this.$refs.bg,
- opacity: 1,
- duration: 100,
- easing: 'linear'
- });
-
anime({
targets: this.$refs.main,
opacity: 1,
@@ -170,33 +168,27 @@ export default Vue.extend({
this.close();
},
+ onBgClick() {
+ if (this.cancelableByBgClick) this.cancel();
+ }
+
close() {
+ this.$refs.modal.close();
+ },
+
+ onBeforeClose() {
this.$el.style.pointerEvents = 'none';
- (this.$refs.bg as any).style.pointerEvents = 'none';
(this.$refs.main as any).style.pointerEvents = 'none';
anime({
- targets: this.$refs.bg,
- opacity: 0,
- duration: 300,
- easing: 'linear'
- });
- anime({
targets: this.$refs.main,
opacity: 0,
scale: 0.8,
duration: 300,
easing: 'cubicBezier(0, 0.5, 0.5, 1)',
- complete: () => this.destroyDom()
});
},
- onBgClick() {
- if (this.cancelableByBgClick) {
- this.cancel();
- }
- },
-
onInputKeydown(e) {
if (e.which == 13) { // Enter
e.preventDefault();
@@ -209,80 +201,63 @@ export default Vue.extend({
</script>
<style lang="stylus" scoped>
-.felqjxyj
+.modal
display flex
align-items center
justify-content center
- position fixed
- z-index 30000
- top 0
- left 0
- width 100%
- height 100%
&.splash
> .main
min-width 0
width initial
- > .bg
- display block
- position fixed
- top 0
- left 0
- width 100%
- height 100%
- background rgba(#000, 0.7)
- opacity 0
- pointer-events none
-
- > .main
- display block
- position fixed
- margin auto
- padding 32px
- min-width 320px
- max-width 480px
- width calc(100% - 32px)
- text-align center
- background var(--face)
- color var(--faceText)
- opacity 0
+.main
+ display block
+ position fixed
+ margin auto
+ padding 32px
+ min-width 320px
+ max-width 480px
+ width calc(100% - 32px)
+ text-align center
+ background var(--face)
+ color var(--faceText)
+ opacity 0
- &.round
- border-radius 8px
+ &.round
+ border-radius 8px
- > .icon
- font-size 32px
+ > .icon
+ font-size 32px
- &.success
- color #85da5a
+ &.success
+ color #85da5a
- &.error
- color #ec4137
+ &.error
+ color #ec4137
- &.warning
- color #ecb637
+ &.warning
+ color #ecb637
- > *
- display block
- margin 0 auto
+ > *
+ display block
+ margin 0 auto
- & + header
- margin-top 16px
+ & + header
+ margin-top 16px
- > header
- margin 0 0 8px 0
- font-weight bold
- font-size 20px
+ > header
+ margin 0 0 8px 0
+ font-weight bold
+ font-size 20px
- & + .body
- margin-top 8px
+ & + .body
+ margin-top 8px
- > .body
- margin 16px 0 0 0
+ > .body
+ margin 16px 0 0 0
- > .buttons
- margin-top 16px
+ > .buttons
+ margin-top 16px
</style>
diff --git a/src/client/app/common/views/components/image-viewer.vue b/src/client/app/common/views/components/image-viewer.vue
index 7787942ca8..63b5e28d00 100644
--- a/src/client/app/common/views/components/image-viewer.vue
+++ b/src/client/app/common/views/components/image-viewer.vue
@@ -1,24 +1,14 @@
<template>
-<div class="dkjvrdxtkvqrwmhfickhndpmnncsgacq" v-hotkey.global="keymap">
- <div class="bg" @click="close"></div>
- <img :src="image.url" :alt="image.name" :title="image.name" @click="close"/>
-</div>
+<ui-modal ref="modal" v-hotkey.global="keymap">
+ <img :src="image.url" :alt="image.name" :title="image.name" @click="close" />
+</ui-modal>
</template>
<script lang="ts">
import Vue from 'vue';
-import anime from 'animejs';
export default Vue.extend({
props: ['image'],
- mounted() {
- anime({
- targets: this.$el,
- opacity: 1,
- duration: 100,
- easing: 'linear'
- });
- },
computed: {
keymap(): any {
return {
@@ -28,50 +18,24 @@ export default Vue.extend({
},
methods: {
close() {
- anime({
- targets: this.$el,
- opacity: 0,
- duration: 100,
- easing: 'linear',
- complete: () => this.destroyDom()
- });
+ (this.$refs.modal as any).close();
}
}
});
</script>
<style lang="stylus" scoped>
-.dkjvrdxtkvqrwmhfickhndpmnncsgacq
- display block
+img
position fixed
- z-index 2048
+ z-index 2
top 0
+ right 0
+ bottom 0
left 0
- width 100%
- height 100%
- opacity 0
-
- > .bg
- display block
- position fixed
- z-index 1
- top 0
- left 0
- width 100%
- height 100%
- background rgba(#000, 0.7)
-
- > img
- position fixed
- z-index 2
- top 0
- right 0
- bottom 0
- left 0
- max-width 100%
- max-height 100%
- margin auto
- cursor zoom-out
- image-orientation from-image
+ max-width 100%
+ max-height 100%
+ margin auto
+ cursor zoom-out
+ image-orientation from-image
</style>
diff --git a/src/client/app/common/views/components/index.ts b/src/client/app/common/views/components/index.ts
index 4253118ba8..88cd4931d4 100644
--- a/src/client/app/common/views/components/index.ts
+++ b/src/client/app/common/views/components/index.ts
@@ -47,6 +47,7 @@ import uiInfo from './ui/info.vue';
import uiMargin from './ui/margin.vue';
import uiHr from './ui/hr.vue';
import uiPagination from './ui/pagination.vue';
+import uiModal from './ui/modal.vue';
import formButton from './ui/form/button.vue';
import formRadio from './ui/form/radio.vue';
@@ -97,5 +98,6 @@ Vue.component('ui-info', uiInfo);
Vue.component('ui-margin', uiMargin);
Vue.component('ui-hr', uiHr);
Vue.component('ui-pagination', uiPagination);
+Vue.component('ui-modal', uiModal);
Vue.component('form-button', formButton);
Vue.component('form-radio', formRadio);
diff --git a/src/client/app/common/views/components/ui/modal.vue b/src/client/app/common/views/components/ui/modal.vue
new file mode 100644
index 0000000000..413dc39fa5
--- /dev/null
+++ b/src/client/app/common/views/components/ui/modal.vue
@@ -0,0 +1,80 @@
+<template>
+<div class="modal">
+ <div class="bg" ref="bg" @click="onBgClick" />
+ <slot class="main" />
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import anime from 'animejs';
+
+export default Vue.extend({
+ props: {
+ closeOnBgClick: {
+ type: Boolean,
+ required: false,
+ default: true
+ },
+ openAnimeDuration: {
+ type: Number,
+ required: false,
+ default: 100
+ },
+ closeAnimeDuration: {
+ type: Number,
+ required: false,
+ default: 100
+ }
+ },
+ mounted() {
+ anime({
+ targets: this.$refs.bg,
+ opacity: 1,
+ duration: this.openAnimeDuration,
+ easing: 'linear'
+ });
+ },
+ methods: {
+ onBgClick() {
+ this.$emit('bg-click');
+ if (this.closeOnBgClick) this.close();
+ },
+ close() {
+ this.$emit('before-close');
+
+ anime({
+ targets: this.$refs.bg,
+ opacity: 0,
+ duration: this.closeAnimeDuration,
+ easing: 'linear',
+ complete: () => (this as any).destroyDom()
+ });
+ }
+ }
+});
+</script>
+
+<style lang="stylus" scoped>
+.modal
+ position fixed
+ z-index 2048
+ top 0
+ left 0
+ width 100%
+ height 100%
+
+.bg
+ display block
+ position fixed
+ z-index 1
+ top 0
+ left 0
+ width 100%
+ height 100%
+ background rgba(#000, 0.7)
+ opacity 0
+
+.main
+ z-index 1
+</style>
diff --git a/src/client/app/desktop/views/components/media-video-dialog.vue b/src/client/app/desktop/views/components/media-video-dialog.vue
index 803350506a..9d2d0527ef 100644
--- a/src/client/app/desktop/views/components/media-video-dialog.vue
+++ b/src/client/app/desktop/views/components/media-video-dialog.vue
@@ -1,23 +1,15 @@
<template>
-<div class="mk-media-video-dialog" v-hotkey.global="keymap">
- <div class="bg" @click="close"></div>
- <video :src="video.url" :title="video.name" controls autoplay ref="video" @volumechange="volumechange"/>
-</div>
+<ui-modal v-hotkey.global="keymap">
+ <video :src="video.url" :title="video.name" controls autoplay ref="video" @volumechange="volumechange" />
+</ui-modal>
</template>
<script lang="ts">
import Vue from 'vue';
-import anime from 'animejs';
export default Vue.extend({
props: ['video', 'start'],
mounted() {
- anime({
- targets: this.$el,
- opacity: 1,
- duration: 100,
- easing: 'linear'
- });
const videoTag = this.$refs.video as HTMLVideoElement;
if (this.start) videoTag.currentTime = this.start
videoTag.volume = this.$store.state.device.mediaVolume;
@@ -31,13 +23,6 @@ export default Vue.extend({
},
methods: {
close() {
- anime({
- targets: this.$el,
- opacity: 0,
- duration: 100,
- easing: 'linear',
- complete: () => this.destroyDom()
- });
},
volumechange() {
const videoTag = this.$refs.video as HTMLVideoElement;
@@ -48,35 +33,15 @@ export default Vue.extend({
</script>
<style lang="stylus" scoped>
-.mk-media-video-dialog
- display block
+video
position fixed
- z-index 2048
+ z-index 2
top 0
+ right 0
+ bottom 0
left 0
- width 100%
- height 100%
- opacity 0
-
- > .bg
- display block
- position fixed
- z-index 1
- top 0
- left 0
- width 100%
- height 100%
- background rgba(#000, 0.7)
-
- > video
- position fixed
- z-index 2
- top 0
- right 0
- bottom 0
- left 0
- max-width 80vw
- max-height 80vh
- margin auto
+ max-width 80vw
+ max-height 80vh
+ margin auto
</style>
diff --git a/src/client/app/mobile/views/components/post-form-dialog.vue b/src/client/app/mobile/views/components/post-form-dialog.vue
index 716ad8fd07..4ae79dbd7b 100644
--- a/src/client/app/mobile/views/components/post-form-dialog.vue
+++ b/src/client/app/mobile/views/components/post-form-dialog.vue
@@ -1,6 +1,9 @@
<template>
-<div class="ulveipglmagnxfgvitaxyszerjwiqmwl">
- <div class="bg" ref="bg"></div>
+<ui-modal
+ ref="modal"
+ :close-on-bg-click="false"
+ :close-anime-duration="300"
+ @before-close="onBeforeClose">
<div class="main" ref="main">
<x-post-form ref="form"
:reply="reply"
@@ -12,7 +15,7 @@
@posted="onPosted"
@cancel="onCanceled"/>
</div>
-</div>
+</ui-modal>
</template>
<script lang="ts">
@@ -55,14 +58,6 @@ export default Vue.extend({
mounted() {
this.$nextTick(() => {
- (this.$refs.bg as any).style.pointerEvents = 'auto';
- anime({
- targets: this.$refs.bg,
- opacity: 1,
- duration: 100,
- easing: 'linear'
- });
-
anime({
targets: this.$refs.main,
opacity: 1,
@@ -78,26 +73,22 @@ export default Vue.extend({
this.$refs.form.focus();
},
- close() {
- (this.$refs.bg as any).style.pointerEvents = 'none';
- anime({
- targets: this.$refs.bg,
- opacity: 0,
- duration: 300,
- easing: 'linear'
- });
-
+ onBeforeClose() {
(this.$refs.main as any).style.pointerEvents = 'none';
+
anime({
targets: this.$refs.main,
opacity: 0,
translateY: 16,
duration: 300,
- easing: 'easeOutQuad',
- complete: () => this.destroyDom()
+ easing: 'easeOutQuad'
});
},
+ close() {
+ (this.$refs.modal as any).close();
+ },
+
onPosted() {
this.$emit('posted');
this.close();
@@ -112,30 +103,18 @@ export default Vue.extend({
</script>
<style lang="stylus" scoped>
-.ulveipglmagnxfgvitaxyszerjwiqmwl
- > .bg
- display block
- position fixed
- z-index 10000
- top 0
- left 0
- width 100%
- height 100%
- background rgba(#000, 0.7)
- opacity 0
- pointer-events none
- > .main
- display block
- position fixed
- z-index 10000
- top 0
- left 0
- right 0
- height 100%
- overflow auto
- margin 0 auto 0 auto
- opacity 0
- transform translateY(-16px)
+.main
+ display block
+ position fixed
+ z-index 10000
+ top 0
+ left 0
+ right 0
+ height 100%
+ overflow auto
+ margin 0 auto 0 auto
+ opacity 0
+ transform translateY(-16px)
</style>