change snackbar to nitivue
This commit is contained in:
Generated
+23
@@ -14,6 +14,7 @@
|
|||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
"core-js": "^3.37.1",
|
"core-js": "^3.37.1",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
|
"notivue": "^2.4.4",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"qrcode.vue": "^3.4.1",
|
"qrcode.vue": "^3.4.1",
|
||||||
"roboto-fontface": "^0.10.0",
|
"roboto-fontface": "^0.10.0",
|
||||||
@@ -2522,6 +2523,28 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/notivue": {
|
||||||
|
"version": "2.4.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/notivue/-/notivue-2.4.4.tgz",
|
||||||
|
"integrity": "sha512-d9RaXMbSQD1DS0rrA5WCfql2xm5nXOq1U1nnf8bgQ1LRHu4UsLY57Bdc9O9SHTpR1gDmm/pSxq7gocitzDtMpw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nuxt/kit": ">=3.5.0",
|
||||||
|
"@nuxt/schema": ">=3.5.0",
|
||||||
|
"defu": ">=6"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@nuxt/kit": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@nuxt/schema": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"defu": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/nth-check": {
|
"node_modules/nth-check": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
"core-js": "^3.37.1",
|
"core-js": "^3.37.1",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
|
"notivue": "^2.4.4",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"qrcode.vue": "^3.4.1",
|
"qrcode.vue": "^3.4.1",
|
||||||
"roboto-fontface": "^0.10.0",
|
"roboto-fontface": "^0.10.0",
|
||||||
|
|||||||
@@ -1,18 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-snackbar
|
<Notivue v-slot="item">
|
||||||
v-model="sb.showMsg"
|
<NotivueSwipe :item="item">
|
||||||
location="top"
|
<Notification
|
||||||
:color="snackbar.color"
|
:item="item"
|
||||||
:timeout="snackbar.timeout">
|
:theme="theme"
|
||||||
{{ snackbar.message }}
|
:dir="direction"
|
||||||
</v-snackbar>
|
:icons="outlinedIcons"
|
||||||
|
:hideClose="true"
|
||||||
|
@click="item.clear"
|
||||||
|
/>
|
||||||
|
</NotivueSwipe>
|
||||||
|
</Notivue>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue'
|
import { Notivue, Notification, NotivueSwipe, outlinedIcons, pastelTheme, darkTheme } from 'notivue'
|
||||||
import Message from '@/store/modules/message'
|
import { computed } from 'vue'
|
||||||
|
import { useTheme } from 'vuetify'
|
||||||
|
import vuetify from '@/plugins/vuetify';
|
||||||
|
|
||||||
const sb = Message()
|
const Theme = useTheme()
|
||||||
|
|
||||||
const snackbar = ref(sb.snackbar)
|
const theme = computed(() =>{
|
||||||
|
return Theme.global.name.value == "light" ? pastelTheme : darkTheme
|
||||||
|
})
|
||||||
|
|
||||||
|
const direction = computed(() => {
|
||||||
|
return vuetify.locale.current.value == 'fa' ? 'rtl' : 'ltr'
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--nv-z: 10020;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<v-row>
|
<v-row>
|
||||||
<v-col>QrCode</v-col>
|
<v-col>QrCode</v-col>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-col cols="1"><v-icon icon="mdi-close-box" @click="$emit('close')" ></v-icon></v-col>
|
<v-col cols="auto"><v-icon icon="mdi-close-box" @click="$emit('close')" /></v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-divider></v-divider>
|
<v-divider></v-divider>
|
||||||
@@ -31,14 +31,13 @@
|
|||||||
import QrcodeVue from 'qrcode.vue'
|
import QrcodeVue from 'qrcode.vue'
|
||||||
import Data from '@/store/modules/data'
|
import Data from '@/store/modules/data'
|
||||||
import Clipboard from 'clipboard'
|
import Clipboard from 'clipboard'
|
||||||
import Message from '@/store/modules/message'
|
|
||||||
import { i18n } from '@/locales'
|
import { i18n } from '@/locales'
|
||||||
|
import { push } from 'notivue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['index'],
|
props: ['index'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
msg: Message(),
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -54,12 +53,18 @@ export default {
|
|||||||
|
|
||||||
clipboard.on('success', () => {
|
clipboard.on('success', () => {
|
||||||
clipboard.destroy()
|
clipboard.destroy()
|
||||||
this.msg.showMessage(i18n.global.t('copyToClipboard') + " : " + i18n.global.t('success'),'success',5000)
|
push.success({
|
||||||
|
message: i18n.global.t('success') + ": " + i18n.global.t('copyToClipboard'),
|
||||||
|
duration: 5000,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
clipboard.on('error', () => {
|
clipboard.on('error', () => {
|
||||||
clipboard.destroy()
|
clipboard.destroy()
|
||||||
this.msg.showMessage(i18n.global.t('copyToClipboard') + " : " + i18n.global.t('failed'),'error',5000)
|
push.error({
|
||||||
|
message: i18n.global.t('failed') + ": " + i18n.global.t('copyToClipboard'),
|
||||||
|
duration: 5000,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Perform click on hidden button to trigger copy
|
// Perform click on hidden button to trigger copy
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
count: "Count",
|
count: "Count",
|
||||||
error: {
|
error: {
|
||||||
dplData: "Duplicate Data",
|
dplData: "Duplicate Data",
|
||||||
|
core: "Sing-Box Error",
|
||||||
},
|
},
|
||||||
pages: {
|
pages: {
|
||||||
login: "Login",
|
login: "Login",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
count: "تعداد",
|
count: "تعداد",
|
||||||
error: {
|
error: {
|
||||||
dplData: "داده تکراری",
|
dplData: "داده تکراری",
|
||||||
|
core: "خطا در سینگباکس",
|
||||||
},
|
},
|
||||||
pages: {
|
pages: {
|
||||||
login: "ورود",
|
login: "ورود",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
count: "Đếm",
|
count: "Đếm",
|
||||||
error: {
|
error: {
|
||||||
dplData: "Dữ liệu trùng lặp",
|
dplData: "Dữ liệu trùng lặp",
|
||||||
|
core: "Lỗi Sing-Box",
|
||||||
},
|
},
|
||||||
pages: {
|
pages: {
|
||||||
login: "Đăng nhập",
|
login: "Đăng nhập",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
count: "计数",
|
count: "计数",
|
||||||
error: {
|
error: {
|
||||||
dplData: "重复数据",
|
dplData: "重复数据",
|
||||||
|
core: "Sing-Box 错误",
|
||||||
},
|
},
|
||||||
pages: {
|
pages: {
|
||||||
login: "登录",
|
login: "登录",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export default {
|
|||||||
count: "計數",
|
count: "計數",
|
||||||
error: {
|
error: {
|
||||||
dplData: "重複數據",
|
dplData: "重複數據",
|
||||||
|
core: "Sing-Box 錯誤",
|
||||||
},
|
},
|
||||||
pages: {
|
pages: {
|
||||||
login: "登錄",
|
login: "登錄",
|
||||||
|
|||||||
@@ -23,6 +23,22 @@ import { registerPlugins } from '@/plugins'
|
|||||||
import { i18n } from '@/locales'
|
import { i18n } from '@/locales'
|
||||||
import Vue3PersianDatetimePicker from 'vue3-persian-datetime-picker'
|
import Vue3PersianDatetimePicker from 'vue3-persian-datetime-picker'
|
||||||
|
|
||||||
|
// Notivue
|
||||||
|
import { createNotivue } from 'notivue'
|
||||||
|
import 'notivue/notification.css'
|
||||||
|
import 'notivue/animations.css'
|
||||||
|
const notivue = createNotivue({
|
||||||
|
position: 'top-center',
|
||||||
|
limit: 4,
|
||||||
|
enqueue: false,
|
||||||
|
avoidDuplicates: false,
|
||||||
|
notifications: {
|
||||||
|
global: {
|
||||||
|
duration: 3000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
@@ -34,5 +50,6 @@ app
|
|||||||
.use(router)
|
.use(router)
|
||||||
.use(store)
|
.use(store)
|
||||||
.use(i18n)
|
.use(i18n)
|
||||||
|
.use(notivue)
|
||||||
.component('DatePicker', Vue3PersianDatetimePicker)
|
.component('DatePicker', Vue3PersianDatetimePicker)
|
||||||
.mount('#app')
|
.mount('#app')
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import api from './api'
|
import api from './api'
|
||||||
import { i18n } from '@/locales'
|
import { i18n } from '@/locales'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import Message from "@/store/modules/message"
|
import { push } from 'notivue'
|
||||||
|
|
||||||
export interface Msg {
|
export interface Msg {
|
||||||
success: boolean
|
success: boolean
|
||||||
@@ -10,18 +10,27 @@ export interface Msg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _handleMsg(msg: any): void {
|
function _handleMsg(msg: any): void {
|
||||||
const sb = Message()
|
|
||||||
if (!isMsg(msg)) {
|
if (!isMsg(msg)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if(msg.msg){
|
if(msg.msg){
|
||||||
if (!msg.success && msg.msg == "Invalid login") {
|
if (!msg.success && msg.msg == "Invalid login") {
|
||||||
sb.showMessage(i18n.global.t('invalidLogin'),'error', 5000)
|
push.error({
|
||||||
|
title: i18n.global.t('invalidLogin'),
|
||||||
|
})
|
||||||
logout()
|
logout()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const message = msg.success ? i18n.global.t('success') + ": " + i18n.global.t('actions.' + msg.msg) : i18n.global.t('failed') + ": " + msg.msg
|
if (msg.success) {
|
||||||
sb.showMessage(message, msg.success ? 'success' : 'error', 5000)
|
push.success({
|
||||||
|
message: i18n.global.t('success') + ": " + i18n.global.t('actions.' + msg.msg),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
push.error({
|
||||||
|
title: i18n.global.t('failed'),
|
||||||
|
message: msg.msg
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { FindDiff } from '@/plugins/utils'
|
import { FindDiff } from '@/plugins/utils'
|
||||||
import HttpUtils from '@/plugins/httputil'
|
import HttpUtils from '@/plugins/httputil'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import Message from './message'
|
import { push } from 'notivue'
|
||||||
|
import { i18n } from '@/locales'
|
||||||
|
|
||||||
const Data = defineStore('Data', {
|
const Data = defineStore('Data', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
@@ -26,8 +27,11 @@ const Data = defineStore('Data', {
|
|||||||
if (msg.obj.tls) this.oldData.tlsConfigs = msg.obj.tls
|
if (msg.obj.tls) this.oldData.tlsConfigs = msg.obj.tls
|
||||||
this.onlines = msg.obj.onlines
|
this.onlines = msg.obj.onlines
|
||||||
if (msg.obj.lastLog) {
|
if (msg.obj.lastLog) {
|
||||||
const sb = Message()
|
push.error({
|
||||||
sb.showMessage('Core error: \n' + msg.obj.lastLog,'error', 5000)
|
title: i18n.global.t('error.core'),
|
||||||
|
duration: 5000,
|
||||||
|
message: msg.obj.lastLog
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.obj.config) {
|
if (msg.obj.config) {
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
import { defineStore } from 'pinia'
|
|
||||||
|
|
||||||
const Message = defineStore('msg', {
|
|
||||||
state: () => ({
|
|
||||||
showMsg: false,
|
|
||||||
snackbar: {
|
|
||||||
message: '',
|
|
||||||
timeout: 5000,
|
|
||||||
color: '',
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
actions: {
|
|
||||||
showMessage(message:string, color='success',timeout=5000) {
|
|
||||||
this.snackbar.message = message
|
|
||||||
this.snackbar.color = color
|
|
||||||
this.snackbar.timeout = timeout
|
|
||||||
this.showMsg = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
export default Message
|
|
||||||
@@ -135,8 +135,8 @@ import { Config, V2rayApiStats } from '@/types/config'
|
|||||||
import { InTypes, Inbound,InboundWithUser, ShadowTLS, VLESS } from '@/types/inbounds'
|
import { InTypes, Inbound,InboundWithUser, ShadowTLS, VLESS } from '@/types/inbounds'
|
||||||
import { Link, LinkUtil } from '@/plugins/link'
|
import { Link, LinkUtil } from '@/plugins/link'
|
||||||
import { HumanReadable } from '@/plugins/utils'
|
import { HumanReadable } from '@/plugins/utils'
|
||||||
import Message from '@/store/modules/message'
|
|
||||||
import { i18n } from '@/locales'
|
import { i18n } from '@/locales'
|
||||||
|
import { push } from 'notivue'
|
||||||
|
|
||||||
const clients = computed((): any[] => {
|
const clients = computed((): any[] => {
|
||||||
return Data().clients
|
return Data().clients
|
||||||
@@ -185,8 +185,9 @@ const saveModal = (data:any, stats:boolean) => {
|
|||||||
// Check duplicate name
|
// Check duplicate name
|
||||||
const oldName = modal.value.index != -1 ? clients.value[modal.value.index].name : null
|
const oldName = modal.value.index != -1 ? clients.value[modal.value.index].name : null
|
||||||
if (data.name != oldName && clients.value.findIndex(c => c.name == data.name) != -1) {
|
if (data.name != oldName && clients.value.findIndex(c => c.name == data.name) != -1) {
|
||||||
const sb = Message()
|
push.error({
|
||||||
sb.showMessage(i18n.global.t('error.dplData') + ': ' + i18n.global.t('client.name') ,'error', 5000)
|
message: i18n.global.t('error.dplData') + ": " + i18n.global.t('client.name')
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if(modal.value.index == -1) {
|
if(modal.value.index == -1) {
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ import { computed, ref } from 'vue'
|
|||||||
import { InTypes, Inbound, InboundWithUser, ShadowTLS, VLESS } from '@/types/inbounds'
|
import { InTypes, Inbound, InboundWithUser, ShadowTLS, VLESS } from '@/types/inbounds'
|
||||||
import { Client } from '@/types/clients'
|
import { Client } from '@/types/clients'
|
||||||
import { Link, LinkUtil } from '@/plugins/link'
|
import { Link, LinkUtil } from '@/plugins/link'
|
||||||
import Message from '@/store/modules/message'
|
|
||||||
import { i18n } from '@/locales'
|
import { i18n } from '@/locales'
|
||||||
|
import { push } from 'notivue'
|
||||||
|
|
||||||
const appConfig = computed((): Config => {
|
const appConfig = computed((): Config => {
|
||||||
return <Config> Data().config
|
return <Config> Data().config
|
||||||
@@ -166,8 +166,9 @@ const saveModal = (data:Inbound, stats: boolean, tls_id: number) => {
|
|||||||
// Check duplicate tag
|
// Check duplicate tag
|
||||||
const oldTag = modal.value.id != -1 ? inbounds.value[modal.value.id].tag : null
|
const oldTag = modal.value.id != -1 ? inbounds.value[modal.value.id].tag : null
|
||||||
if (data.tag != oldTag && inTags.value.includes(data.tag)) {
|
if (data.tag != oldTag && inTags.value.includes(data.tag)) {
|
||||||
const sb = Message()
|
push.error({
|
||||||
sb.showMessage(i18n.global.t('error.dplData') + ': ' + i18n.global.t('objects.tag') ,'error', 5000)
|
message: i18n.global.t('error.dplData') + ": " + i18n.global.t('objects.tag')
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,8 +96,8 @@ import Stats from '@/layouts/modals/Stats.vue'
|
|||||||
import { Config, V2rayApiStats } from '@/types/config';
|
import { Config, V2rayApiStats } from '@/types/config';
|
||||||
import { Outbound } from '@/types/outbounds';
|
import { Outbound } from '@/types/outbounds';
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import Message from '@/store/modules/message';
|
|
||||||
import { i18n } from '@/locales';
|
import { i18n } from '@/locales';
|
||||||
|
import { push } from 'notivue';
|
||||||
|
|
||||||
const appConfig = computed((): Config => {
|
const appConfig = computed((): Config => {
|
||||||
return <Config> Data().config
|
return <Config> Data().config
|
||||||
@@ -142,8 +142,9 @@ const saveModal = (data:Outbound, stats: boolean) => {
|
|||||||
// Check duplicate tag
|
// Check duplicate tag
|
||||||
const oldTag = modal.value.id != -1 ? outbounds.value[modal.value.id].tag : null
|
const oldTag = modal.value.id != -1 ? outbounds.value[modal.value.id].tag : null
|
||||||
if (data.tag != oldTag && outboundTags.value.includes(data.tag)) {
|
if (data.tag != oldTag && outboundTags.value.includes(data.tag)) {
|
||||||
const sb = Message()
|
push.error({
|
||||||
sb.showMessage(i18n.global.t('error.dplData') + ': ' + i18n.global.t('objects.tag') ,'error', 5000)
|
message: i18n.global.t('error.dplData') + ": " + i18n.global.t('objects.tag')
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// New or Edit
|
// New or Edit
|
||||||
|
|||||||
Reference in New Issue
Block a user