diff --git a/src/components/CardWidget.vue b/src/components/CardWidget.vue index b622128..710ef71 100644 --- a/src/components/CardWidget.vue +++ b/src/components/CardWidget.vue @@ -4,6 +4,7 @@ footer-tag="footer" no-body class="mb-4 card-custom" + :class="highlighted ? 'highlight' : ''" >
@@ -92,6 +93,10 @@ const props = defineProps({ type: String, default: '', }, + highlighted: { + type: Boolean, + default: false, + }, status: { type: Object as PropType< | { diff --git a/src/components/ChannelSelector.vue b/src/components/ChannelSelector.vue new file mode 100644 index 0000000..2396111 --- /dev/null +++ b/src/components/ChannelSelector.vue @@ -0,0 +1,228 @@ + + + + diff --git a/src/global-styles/custom.scss b/src/global-styles/custom.scss index 318576d..b66a0da 100644 --- a/src/global-styles/custom.scss +++ b/src/global-styles/custom.scss @@ -233,6 +233,12 @@ button { &:hover { box-shadow: var(--card-shadow-hover); } + &.highlight { + box-shadow: var(--card-shadow), 0 0 0 3px var(--bs-primary); + &:hover { + box-shadow: var(--card-shadow-hover), 0 0 0 3px var(--bs-primary); + } + } border: none !important; outline: 0 !important; // Loading bar safari bug https://gist.github.com/ayamflow/b602ab436ac9f05660d9c15190f4fd7b @@ -915,3 +921,8 @@ html[data-theme='dark'] { .btn svg { width: 24px; } + +.card-grid { + display: grid; + grid-column-gap: 1rem; +} diff --git a/src/store/apps.ts b/src/store/apps.ts index dc6c61d..c65a86a 100644 --- a/src/store/apps.ts +++ b/src/store/apps.ts @@ -51,7 +51,7 @@ export default defineStore('apps', { const poll = window.setInterval(async () => { await this.getInstalledApps(); - const index = this.installed.findIndex((app) => app.id === appId); + const index = this.installed.findIndex((app) => app?.id === appId); if (index === -1) { this.uninstalling.splice(this.uninstalling.indexOf(appId), 1); window.clearInterval(poll); @@ -64,7 +64,7 @@ export default defineStore('apps', { const poll = window.setInterval(async () => { await this.getInstalledApps(); - const index = this.installed.findIndex((app) => app.id === appId); + const index = this.installed.findIndex((app) => app?.id === appId); if (index !== -1) { this.installing.splice(this.installing.indexOf(appId), 1); window.clearInterval(poll); diff --git a/src/views/Settings.vue b/src/views/Settings.vue index 4165818..3ca3aee 100644 --- a/src/views/Settings.vue +++ b/src/views/Settings.vue @@ -186,7 +186,6 @@ :success="isCorrectOtp" :error="isIncorrectOtp" @otp-token="setTotpToken" - @keyup="hideOtpError" />
@@ -202,7 +201,7 @@ Incorrect password -
+
Incorrect code
@@ -498,6 +497,27 @@
+
+
+
+ Features + Manage features you want +
+ Manage + +
+
Citadel Version @@ -582,6 +602,7 @@ import useSystemStore from '../store/system'; import useUserStore from '../store/user'; import {defineComponent, DefineComponent} from 'vue'; import useToast from '../utils/toast'; +import ChannelSelector from '../components/ChannelSelector.vue'; export default defineComponent({ components: { @@ -599,6 +620,7 @@ export default defineComponent({ BIconCheckCircleFill, BellIcon: BellIcon as DefineComponent, RefreshIcon: RefreshIcon as DefineComponent, + ChannelSelector, }, setup() { const sdkStore = useSdkStore(); @@ -622,6 +644,7 @@ export default defineComponent({ loadingDebug: false, debugFailed: false, showDmesg: false, + showChannelSelectorModal: false, authenticatorToken: '', } as { currentPassword: string; @@ -639,6 +662,9 @@ export default defineComponent({ showDmesg: boolean; authenticatorToken: string; pollUpdateStatus?: number; + isCorrectOtp: boolean; + isIncorrectOtp: boolean; + showChannelSelectorModal: boolean; }; }, computed: { @@ -654,9 +680,11 @@ export default defineComponent({ if (typeof this.systemStore.debugStatus === 'string') { return 'Error loading data!'; } - return this.showDmesg - ? this.systemStore.debugStatus.dmesg - : this.systemStore.debugStatus.debug; + return ( + this.showDmesg + ? this.systemStore.debugStatus.dmesg + : this.systemStore.debugStatus.debug + ) as string; }, debugFilename(): string { const type: string = this.showDmesg ? 'dmesg' : 'debug'; @@ -698,7 +726,7 @@ export default defineComponent({ } }, methods: { - setTotpToken(totpToken) { + setTotpToken(totpToken: string) { this.totpToken = totpToken; }, async enableTwoFactorAuth() { @@ -768,7 +796,7 @@ export default defineComponent({ async changePassword() { this.isChangingPassword = true; this.isIncorrectPassword = false; - this.isIncorrectTotp = false; + this.isIncorrectOtp = false; try { await this.sdkStore.citadel.manager.auth.changePassword( @@ -788,7 +816,7 @@ export default defineComponent({ const isIncorrectTotp = errorString.includes('Incorrect 2FA code'); this.isIncorrectPassword = isIncorrectPassword; - this.isIncorrectTotp = isIncorrectTotp; + this.isIncorrectOtp = isIncorrectTotp; this.isChangingPassword = false; return; @@ -838,6 +866,12 @@ export default defineComponent({ this.loadingDebug = false; (this.$refs['debug-modal'] as {hide: () => void}).hide(); }, + async openChannelModal() { + this.showChannelSelectorModal = true; + }, + closeChannelModal() { + this.showChannelSelectorModal = false; + }, downloadTextFile(contents: string, fileName: string) { const blob = new Blob([contents], { type: 'text/plain;charset=utf-8;',