Adjust display in dark mode and add manual control support for dark mode.
parent
a16cf5d98f
commit
c85cbcd397
|
|
@ -28,6 +28,8 @@ declare module '@vue/runtime-core' {
|
|||
AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider']
|
||||
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
|
||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASkeleton: typeof import('ant-design-vue/es')['Skeleton']
|
||||
ASlider: typeof import('ant-design-vue/es')['Slider']
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue'
|
||||
import { onMounted, watch } from 'vue'
|
||||
import { getGlobalSetting } from './api'
|
||||
import { useGlobalStore } from './store/useGlobalStore'
|
||||
import { getQuickMovePaths } from '@/page/taskRecord/autoComplete'
|
||||
|
|
@ -9,6 +9,8 @@ import { resolveQueryActions } from './queryActions'
|
|||
import { refreshTauriConf, tauriConf } from './util/tauriAppConf'
|
||||
import { openModal } from './taurilaunchModal'
|
||||
import { isTauri } from './util/env'
|
||||
import { usePreferredDark } from '@vueuse/core'
|
||||
import { delay } from 'vue3-ts-util'
|
||||
|
||||
const globalStore = useGlobalStore()
|
||||
const queue = createReactiveQueue()
|
||||
|
|
@ -39,6 +41,30 @@ useGlobalEventListen('returnToIIB', async () => {
|
|||
const r = await getQuickMovePaths(conf)
|
||||
globalStore.quickMovePaths = r.filter((v) => v?.dir?.trim?.())
|
||||
})
|
||||
|
||||
|
||||
|
||||
watch(
|
||||
() => globalStore.computedTheme === 'dark',
|
||||
async (enableDark) => {
|
||||
await delay()
|
||||
const head = document.getElementsByTagName('html')[0] // html而不是head保证优先级
|
||||
if (enableDark) {
|
||||
document.body.classList.add('dark')
|
||||
const darkStyle = document.createElement('style')
|
||||
const { default: css } = await import('ant-design-vue/dist/antd.dark.css?inline')
|
||||
darkStyle.innerHTML = css
|
||||
darkStyle.setAttribute('antd-dark', '')
|
||||
head.appendChild(darkStyle)
|
||||
} else {
|
||||
document.body.classList.remove('dark')
|
||||
Array.from(head.querySelectorAll('style[antd-dark]')).forEach((e) => e.remove())
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
|
||||
onMounted(async () => {
|
||||
if (isTauri) {
|
||||
openModal()
|
||||
|
|
|
|||
|
|
@ -65,15 +65,17 @@ $success-color: #28a745;
|
|||
--zp-border: var(--zp-grey20);
|
||||
--zp-icon-bg: #0004;
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--zp-primary: var(--zp-grey20);
|
||||
--zp-secondary: var(--zp-grey60);
|
||||
--zp-tertiary: var(--zp-grey70);
|
||||
--zp-primary-background: var(--zp-black);
|
||||
--zp-secondary-background: var(--zp-grey96);
|
||||
--zp-secondary-variant-background: var(--zp-grey90);
|
||||
--zp-tertiary-background: var(--zp-grey4);
|
||||
--zp-border: var(--zp-grey96);
|
||||
--zp-icon-bg: #fff4;
|
||||
.body:not(.dark) {
|
||||
--zp-primary: var(--zp-grey20);
|
||||
--zp-secondary: var(--zp-grey60);
|
||||
--zp-tertiary: var(--zp-grey70);
|
||||
--zp-primary-background: var(--zp-black);
|
||||
--zp-secondary-background: var(--zp-grey96);
|
||||
--zp-secondary-variant-background: var(--zp-grey90);
|
||||
--zp-tertiary-background: var(--zp-grey4);
|
||||
--zp-border: var(--zp-grey96);
|
||||
--zp-icon-bg: #fff4;
|
||||
}
|
||||
}
|
||||
body.dark {
|
||||
--zp-primary: var(--zp-grey20);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { createApp, watch } from 'vue'
|
||||
import { createApp } from 'vue'
|
||||
import type {} from 'antd-vue-volar'
|
||||
// @ts-ignore
|
||||
import App from './App.vue'
|
||||
|
|
@ -8,10 +8,8 @@ import 'ant-design-vue/es/modal/style'
|
|||
import './index.scss'
|
||||
import { createPinia } from 'pinia'
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
import { usePreferredDark } from '@vueuse/core'
|
||||
import { i18n } from './i18n'
|
||||
import { delay } from 'vue3-ts-util'
|
||||
import VueDiff from 'vue-diff';
|
||||
import VueDiff from 'vue-diff'
|
||||
|
||||
import 'vue-diff/dist/index.css';
|
||||
|
||||
|
|
@ -25,35 +23,3 @@ createApp(App)
|
|||
})
|
||||
.mount('#zanllp_dev_gradio_fe')
|
||||
|
||||
|
||||
const dark = usePreferredDark()
|
||||
|
||||
const getParDark = () => {
|
||||
try {
|
||||
return parent.location.search.includes('theme=dark') // sd-webui的
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
watch(
|
||||
[dark, getParDark],
|
||||
async ([selfdark, pardark]) => {
|
||||
await delay()
|
||||
const head = document.getElementsByTagName('html')[0] // html而不是head保证优先级
|
||||
if (selfdark || pardark) {
|
||||
document.body.classList.add('dark')
|
||||
const darkStyle = document.createElement('style')
|
||||
const { default: css } = await import('ant-design-vue/dist/antd.dark.css?inline')
|
||||
darkStyle.innerHTML = css
|
||||
darkStyle.setAttribute('antd-dark', '')
|
||||
head.appendChild(darkStyle)
|
||||
} else {
|
||||
document.body.classList.remove('dark')
|
||||
Array.from(head.querySelectorAll('style[antd-dark]')).forEach((e) => e.remove())
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ const maxEdge = asyncComputed(async () => {
|
|||
|
||||
.hint-inline {
|
||||
display: inline-block;
|
||||
color: var(--main-text-color);
|
||||
color: var(--zp-primary);
|
||||
margin: 0 auto;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
|
|
@ -79,14 +79,10 @@ const maxEdge = asyncComputed(async () => {
|
|||
.img-sli .default-theme {
|
||||
|
||||
.splitpanes__splitter {
|
||||
background-color: #ccc;
|
||||
background-color: var(--zp-tertiary);
|
||||
position: relative;
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
.splitpanes {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
@ -15,7 +15,7 @@ const splitpane = ref<{ requestFullScreen (): void }>()
|
|||
<div class="actions">
|
||||
<AButton @click="sli.drawerVisible = false">{{ $t('close') }}</AButton>
|
||||
<AButton @click="splitpane?.requestFullScreen()">{{ $t('fullscreenview') }}</AButton>
|
||||
<a-alert banner style="height: 32px;" :message="'👇 '+$t('scrollDownToComparePrompt')" type="info" show-icon />
|
||||
<a-alert banner style="height: 32px;" :message="'👇 ' + $t('scrollDownToComparePrompt')" type="info" show-icon />
|
||||
</div>
|
||||
</template>
|
||||
</ADrawer>
|
||||
|
|
@ -30,7 +30,6 @@ const splitpane = ref<{ requestFullScreen (): void }>()
|
|||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
|
||||
.img-sli {
|
||||
|
||||
.ant-drawer-header,
|
||||
|
|
@ -39,16 +38,17 @@ const splitpane = ref<{ requestFullScreen (): void }>()
|
|||
}
|
||||
|
||||
.default-theme {
|
||||
|
||||
.splitpanes__splitter {
|
||||
background-color: #ccc;
|
||||
background-color: var(--zp-tertiary);
|
||||
position: relative;
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
.splitpanes {
|
||||
background-color: #f8f8f8;
|
||||
|
||||
.splitpanes__pane {
|
||||
background: var(--zp-primary-background);
|
||||
}
|
||||
|
||||
}
|
||||
}</style>
|
||||
}
|
||||
</style>
|
||||
|
|
@ -6,6 +6,7 @@ import { getImageGenerationInfo } from '@/api'
|
|||
import { watch, ref } from 'vue'
|
||||
import { createReactiveQueue } from '@/util'
|
||||
import { parse } from 'stable-diffusion-image-metadata'
|
||||
import { useGlobalStore } from '@/store/useGlobalStore'
|
||||
|
||||
const props = defineProps<{
|
||||
lImg: FileNodeInfo,
|
||||
|
|
@ -13,6 +14,7 @@ const props = defineProps<{
|
|||
}>()
|
||||
|
||||
const q = createReactiveQueue()
|
||||
const g = useGlobalStore()
|
||||
const lImgInfo = ref("")
|
||||
const rImgInfo = ref("")
|
||||
let seenKeys = []
|
||||
|
|
@ -60,7 +62,7 @@ watch(
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<VueDiff class="diff" mode="split" theme="light" language="plaintext" :prev="lImgInfo" :current="rImgInfo">
|
||||
<VueDiff class="diff" mode="split" :theme="g.computedTheme" language="plaintext" :prev="lImgInfo" :current="rImgInfo">
|
||||
</VueDiff>
|
||||
</template>
|
||||
|
||||
|
|
@ -68,9 +70,6 @@ watch(
|
|||
.diff {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
background-color: rgba(255, 255, 255, 0.5) !important;
|
||||
|
||||
color: #f8f8f8;
|
||||
backdrop-filter: blur(5px);
|
||||
transition: top 0.2s ease-in-out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ const restoreRecord = () => {
|
|||
<LockOutlined title="Access Control mode" style="vertical-align: text-bottom;" />
|
||||
</div>
|
||||
<div flex-placeholder />
|
||||
|
||||
<a href="https://github.com/zanllp/sd-webui-infinite-image-browsing" target="_blank" class="last-record">Github</a>
|
||||
<a href="https://github.com/zanllp/sd-webui-infinite-image-browsing/blob/main/.env.example" target="_blank"
|
||||
class="last-record">{{ $t('privacyAndSecurity') }}</a>
|
||||
|
|
@ -110,6 +111,11 @@ const restoreRecord = () => {
|
|||
class="last-record">{{ $t('changlog') }}</a>
|
||||
<a href="https://github.com/zanllp/sd-webui-infinite-image-browsing/issues/90" target="_blank"
|
||||
class="last-record">{{ $t('faq') }}</a>
|
||||
<a-radio-group v-model:value="global.darkModeControl" button-style="solid">
|
||||
<a-radio-button value="light">light</a-radio-button>
|
||||
<a-radio-button value="auto">auto</a-radio-button>
|
||||
<a-radio-button value="dark">dark</a-radio-button>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
<a-alert show-icon v-if="global.conf?.enable_access_control && !global.dontShowAgain">
|
||||
<template #message>
|
||||
|
|
@ -244,7 +250,7 @@ const restoreRecord = () => {
|
|||
}
|
||||
|
||||
.last-record {
|
||||
margin-left: 16px;
|
||||
margin-right: 16px;
|
||||
font-size: 14px;
|
||||
color: var(--zp-secondary);
|
||||
flex-shrink: 0;
|
||||
|
|
|
|||
|
|
@ -324,8 +324,8 @@ const copyPositivePrompt = () => {
|
|||
line-height: 1.78em;
|
||||
|
||||
:deep(span) {
|
||||
background: rgba(0, 0, 0, 0.06);
|
||||
color: black;
|
||||
background: var(--zp-secondary-variant-background);
|
||||
color: var(--zp-primary);
|
||||
padding: 2px 4px;
|
||||
border-radius: 4px;
|
||||
margin-right: 4px;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { getPreferredLang } from '@/i18n'
|
|||
import { SortMethod } from '@/page/fileTransfer/fileSort'
|
||||
import type { getQuickMovePaths } from '@/page/taskRecord/autoComplete'
|
||||
import { type Dict, type ReturnTypeAsync } from '@/util'
|
||||
import { usePreferredDark } from '@vueuse/core'
|
||||
import { cloneDeep, uniqueId } from 'lodash-es'
|
||||
import { defineStore } from 'pinia'
|
||||
import { VNode, computed, onMounted, reactive, toRaw, watch } from 'vue'
|
||||
|
|
@ -98,6 +99,7 @@ export const useGlobalStore = defineStore(
|
|||
const gridThumbnailResolution = ref(512)
|
||||
const defaultSortingMethod = ref(SortMethod.CREATED_TIME_DESC)
|
||||
const defaultGridCellWidth = ref(256)
|
||||
const darkModeControl = ref<'light' | 'dark' | 'auto'>('auto')
|
||||
|
||||
const createEmptyPane = (): TabPane => ({
|
||||
type: 'empty',
|
||||
|
|
@ -176,7 +178,22 @@ export const useGlobalStore = defineStore(
|
|||
|
||||
const ignoredConfirmActions = reactive<Record<ActionConfirmRequired, boolean>>({ deleteOneOnly: false })
|
||||
|
||||
const dark = usePreferredDark()
|
||||
|
||||
const computedTheme = computed(() => {
|
||||
const getParDark = () => {
|
||||
try {
|
||||
return parent.location.search.includes('theme=dark') // sd-webui的
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
const isDark = darkModeControl.value === 'auto' ? (dark.value || getParDark()) : (darkModeControl.value === 'dark')
|
||||
return isDark ? 'dark' : 'light'
|
||||
})
|
||||
return {
|
||||
computedTheme,
|
||||
darkModeControl,
|
||||
defaultSortingMethod,
|
||||
defaultGridCellWidth,
|
||||
pathAliasMap,
|
||||
|
|
@ -205,6 +222,7 @@ export const useGlobalStore = defineStore(
|
|||
persist: {
|
||||
// debug: true,
|
||||
paths: [
|
||||
'darkModeControl',
|
||||
'dontShowAgainNewImgOpts',
|
||||
'defaultSortingMethod',
|
||||
'defaultGridCellWidth',
|
||||
|
|
|
|||
Loading…
Reference in New Issue