diff --git a/src/App.tsx b/src/App.tsx index 066d5ed..2b4894b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -34,11 +34,14 @@ export default class MainApp extends Vue { Mousetrap.bind('escape', () => { const isFocusPassword = document.querySelector('#password:focus') as HTMLInputElement + const isShowModal = !!PageModule.dialog - if (isFocusPassword) { - isFocusPassword.blur() + if (isShowModal) { + PageModule.closeDialog() } else if (PageModule.menu.view) { PageModule.ASSIGN_MENU({ view: false }) + } else if (isFocusPassword) { + isFocusPassword.blur() } else if (PageModule.activeBlock) { PageModule.closeBlock() } diff --git a/src/components/app/AppButton.tsx b/src/components/app/AppButton.tsx index 0bc2b7a..002593a 100644 --- a/src/components/app/AppButton.tsx +++ b/src/components/app/AppButton.tsx @@ -38,17 +38,18 @@ export default class AppButton extends Vue implements AppButtonPropsInterface { @Prop({ type: String }) target!: string @Prop({ type: Boolean }) loading!: boolean @Prop({ type: Boolean }) nuxt!: boolean + @Prop({ type: String, default: 'transparent' }) color!: string @Prop({ type: Boolean }) disabled!: boolean @Prop({ type: String, default: 'button' }) tag!: string @Prop({ type: [Object, String] }) to!: Route | string @Prop({ type: [Object, String] }) href!: Route | string get classes() { - const classes: any = { [prefix]: true } + const classes: Record = { [prefix]: true, [`${prefix}--${this.color}`]: true } const propertyList: Array = ['fab', 'block'] propertyList.forEach(property => { - classes[`${prefix}--${property}`] = this[property] + classes[`${prefix}--${property}`] = !!this[property] }) return { @@ -106,6 +107,7 @@ export default class AppButton extends Vue implements AppButtonPropsInterface { if (tag === 'button') { data.attrs!.type = this.type + data.attrs!.autofocus = true data.attrs!.disabled = this.disabled } diff --git a/src/components/app/AppDialog.tsx b/src/components/app/AppDialog.tsx new file mode 100644 index 0000000..d2a6233 --- /dev/null +++ b/src/components/app/AppDialog.tsx @@ -0,0 +1,45 @@ +import { Component, Prop, Vue } from 'vue-property-decorator' +import { PageModule } from '@/store/page' +import AppIcon from '@/components/app/AppIcon.vue' +import AppButton from './AppButton' + +// let showDialog = false +@Component({ + components: { AppIcon } +}) +export default class AppDialog extends Vue { + @Prop({ type: Boolean, default: false }) value!: boolean + @Prop({ default: '' }) label!: string + + get dialog() { + return PageModule.dialog + } + + get showDialog() { + return !!this.dialog + } + + generateDialog() { + return
+
+
{ this.$t(this.dialog?.title + '') }
+

{ this.$t(this.dialog?.text + '') }

+ { this.generateButtons() } +
+
+ } + + generateButtons() { + const buttons = this.dialog?.actions.map(({ title, callback }) => { + return { this.$t(title + '') } + }) + + return
{ buttons }
+ } + + render() { + return + { this.showDialog && this.generateDialog() } + + } +} diff --git a/src/components/base/ShutdownButton.tsx b/src/components/base/ShutdownButton.tsx index 2a652d6..3e6ab4e 100644 --- a/src/components/base/ShutdownButton.tsx +++ b/src/components/base/ShutdownButton.tsx @@ -15,13 +15,30 @@ export default class ShutdownBlock extends Vue { shutdown(event: MouseEvent) { event.stopPropagation() - appWindow.lightdm.suspend() + this.openShutdownDialog() + } + + openShutdownDialog() { + PageModule.openDialog({ + title: 'modals.shutdown.title', + text: 'modals.shutdown.text', + actions: [ + { + title: 'text.yes', + callback: appWindow.lightdm.shutdown + }, + { + title: 'text.no', + callback: PageModule.closeDialog + } + ] + }) } render() { const button =
-
+
diff --git a/src/models/page.ts b/src/models/page.ts index d9eedcf..f698ab1 100644 --- a/src/models/page.ts +++ b/src/models/page.ts @@ -49,3 +49,15 @@ export interface AppMenuPosition { top?: number; bottom?: number; } + +export interface DialogButtonInterface { + title: string; + callback: () => void; + +} + +export interface DialogInterface { + title: string; + text: string; + actions: DialogButtonInterface[]; +} diff --git a/src/style/components/button.styl b/src/style/components/button.styl index 601af91..e3aac5b 100644 --- a/src/style/components/button.styl +++ b/src/style/components/button.styl @@ -8,9 +8,14 @@ color black align-items center justify-content center - transition: .3s background + transition: .2s background, .2s border, .2s color &:hover background var(--color-active) + &:focus + border: 1px solid var(--color-active) + background: none + outline: none + color white .app-button--block display: flex; diff --git a/src/style/components/dialog.styl b/src/style/components/dialog.styl new file mode 100644 index 0000000..2148be7 --- /dev/null +++ b/src/style/components/dialog.styl @@ -0,0 +1,30 @@ +.dialog-overlay + width 100% + height 100% + position absolute + display flex + align-items center + justify-content center + background rgba(0, 0, 0, .8) + +.dialog-body + padding: 24px 36px + border-radius: 12px + background rgba(0, 0, 0, .8) + +.dialog-title + text-align center + margin 0 + font-size 3.25rem + +.dialog-text + text-align center + margin-bottom 12px + font-size 1.5rem + +.dialog-buttons + display flex + gap 12px + .app-button + min-width 100px + flex 1 \ No newline at end of file diff --git a/src/style/components/index.styl b/src/style/components/index.styl index a0b57b2..7eeb4f5 100644 --- a/src/style/components/index.styl +++ b/src/style/components/index.styl @@ -1,5 +1,6 @@ @import './menu.styl' @import './login.styl' +@import './dialog.styl' @import './slider.styl' @import './button.styl' @import './palette.styl' diff --git a/src/views/Home.tsx b/src/views/Home.tsx index 9b1edab..8fad3d0 100644 --- a/src/views/Home.tsx +++ b/src/views/Home.tsx @@ -112,6 +112,8 @@ export default class HomePage extends Vue { { !this.isViewThemeOnly && } { this.showGithubButton && } + +
}