新增pwa

This commit is contained in:
eoao
2025-08-30 07:36:38 +08:00
parent 99eca7893d
commit c6a7c6b220
10 changed files with 4545 additions and 88 deletions
+4
View File
@@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="theme-color" content="#D3E3FD" id="theme-color-meta">
<title></title>
<link rel="icon" href="./src/assets/favicon.svg" type="image/svg+xml">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
@@ -13,6 +14,9 @@
const uiStore = JSON.parse(uiStoreStr)
const root = document.documentElement
root.setAttribute('class', uiStore.dark ? 'dark' : '');
const metaTag = document.getElementById('theme-color-meta');
const isMobile = !window.matchMedia("(pointer: fine) and (hover: hover)").matches;
metaTag.setAttribute('content', uiStore.dark ? (isMobile ? '#141414' : '#000000') : (isMobile ? '#FFFFFF' : '#D3E3FD'));
}
</script>
</head>
+4456 -41
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -36,6 +36,7 @@
"terser": "^5.39.0",
"unplugin-auto-import": "^19.3.0",
"unplugin-vue-components": "^28.7.0",
"vite": "6.3.4"
"vite": "6.3.4",
"vite-plugin-pwa": "^1.0.3"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

-1
View File
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

+1 -1
View File
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><g fill="none"><path fill="#367af2" d="M2 10v12.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V10l-13.526 7.292a1 1 0 0 1-.948 0z"/><path fill="url(#fluentColorMail320)" d="M2 10v12.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V10l-13.526 7.292a1 1 0 0 1-.948 0z"/><path fill="url(#fluentColorMail321)" d="M2 10v12.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V10l-13.526 7.292a1 1 0 0 1-.948 0z"/><path fill="url(#fluentColorMail322)" fill-opacity="0.75" d="M2 10v12.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V10l-13.526 7.292a1 1 0 0 1-.948 0z"/><path fill="url(#fluentColorMail323)" fill-opacity="0.7" d="M2 10v12.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V10l-13.526 7.292a1 1 0 0 1-.948 0z"/><path fill="url(#fluentColorMail324)" d="M6.5 5A4.5 4.5 0 0 0 2 9.5v1.09l13.526 7.292a1 1 0 0 0 .948 0L30 10.59V9.5A4.5 4.5 0 0 0 25.5 5z"/><defs><linearGradient id="fluentColorMail320" x1="19.555" x2="26.862" y1="13.332" y2="27.873" gradientUnits="userSpaceOnUse"><stop offset=".199" stop-color="#0094f0" stop-opacity="0"/><stop offset=".431" stop-color="#0094f0"/></linearGradient><linearGradient id="fluentColorMail321" x1="12" x2="4.914" y1="11.79" y2="28.328" gradientUnits="userSpaceOnUse"><stop offset=".191" stop-color="#0094f0" stop-opacity="0"/><stop offset=".431" stop-color="#0094f0"/></linearGradient><linearGradient id="fluentColorMail322" x1="23.383" x2="24.532" y1="20.142" y2="28.575" gradientUnits="userSpaceOnUse"><stop stop-color="#2764e7" stop-opacity="0"/><stop offset="1" stop-color="#2764e7"/></linearGradient><linearGradient id="fluentColorMail323" x1="20.333" x2="22.43" y1="12.088" y2="29.25" gradientUnits="userSpaceOnUse"><stop offset=".533" stop-color="#ff6ce8" stop-opacity="0"/><stop offset="1" stop-color="#ff6ce8"/></linearGradient><linearGradient id="fluentColorMail324" x1="10.318" x2="18.903" y1=".976" y2="23.436" gradientUnits="userSpaceOnUse"><stop stop-color="#6ce0ff"/><stop offset=".462" stop-color="#29c3ff"/><stop offset="1" stop-color="#4894fe"/></linearGradient></defs></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><g fill="none"><path fill="#367af2" d="M4 15.42v18.33A6.25 6.25 0 0 0 10.25 40h27.5A6.25 6.25 0 0 0 44 33.75V15.5L24.582 25.724a1.25 1.25 0 0 1-1.168-.002z"/><path fill="url(#SVG9uDrcZUx)" d="M4 15.42v18.33A6.25 6.25 0 0 0 10.25 40h27.5A6.25 6.25 0 0 0 44 33.75V15.5L24.582 25.724a1.25 1.25 0 0 1-1.168-.002z"/><path fill="url(#SVGkPPLtdEu)" d="M4 15.42v18.33A6.25 6.25 0 0 0 10.25 40h27.5A6.25 6.25 0 0 0 44 33.75V15.5L24.582 25.724a1.25 1.25 0 0 1-1.168-.002z"/><path fill="url(#SVG1EOghF8v)" fill-opacity="0.75" d="M4 15.42v18.33A6.25 6.25 0 0 0 10.25 40h27.5A6.25 6.25 0 0 0 44 33.75V15.5L24.582 25.724a1.25 1.25 0 0 1-1.168-.002z"/><path fill="url(#SVG72PJueUR)" fill-opacity="0.7" d="M4 15.42v18.33A6.25 6.25 0 0 0 10.25 40h27.5A6.25 6.25 0 0 0 44 33.75V15.5L24.582 25.724a1.25 1.25 0 0 1-1.168-.002z"/><path fill="url(#SVGCdktzmgW)" d="M4.02 13.747A6.25 6.25 0 0 1 10.25 8h27.5A6.25 6.25 0 0 1 44 14.25v1.38L24.582 25.854a1.25 1.25 0 0 1-1.168-.002L4 15.551V14.25q0-.254.02-.503"/><defs><linearGradient id="SVG9uDrcZUx" x1="31" x2="39.662" y1="19.5" y2="40.944" gradientUnits="userSpaceOnUse"><stop offset=".199" stop-color="#0094f0" stop-opacity="0"/><stop offset=".431" stop-color="#0094f0"/></linearGradient><linearGradient id="SVGkPPLtdEu" x1="18.286" x2="7.955" y1="18.008" y2="41.831" gradientUnits="userSpaceOnUse"><stop offset=".191" stop-color="#0094f0" stop-opacity="0"/><stop offset=".431" stop-color="#0094f0"/></linearGradient><linearGradient id="SVG1EOghF8v" x1="34.547" x2="36.228" y1="30.084" y2="42.272" gradientUnits="userSpaceOnUse"><stop stop-color="#2764e7" stop-opacity="0"/><stop offset="1" stop-color="#2764e7"/></linearGradient><linearGradient id="SVG72PJueUR" x1="30.191" x2="33.258" y1="18.439" y2="43.244" gradientUnits="userSpaceOnUse"><stop offset=".533" stop-color="#0094f0" stop-opacity="0"/><stop offset="1" stop-color="#0094f0"/></linearGradient><linearGradient id="SVGCdktzmgW" x1="15.883" x2="28.057" y1="2.275" y2="34.261" gradientUnits="userSpaceOnUse"><stop stop-color="#6ce0ff"/><stop offset=".462" stop-color="#29c3ff"/><stop offset="1" stop-color="#4894fe"/></linearGradient></defs></g></svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

+3
View File
@@ -219,6 +219,9 @@ function openDark(e) {
function switchDark(nextIsDark, root) {
root.setAttribute('class', nextIsDark ? 'dark' : '')
const metaTag = document.getElementById('theme-color-meta');
const isMobile = !window.matchMedia("(pointer: fine) and (hover: hover)").matches;
metaTag.setAttribute('content', nextIsDark ? (isMobile ? '#141414' : '#000000') : (isMobile ? '#FFFFFF' : '#D3E3FD'));
uiStore.dark = nextIsDark
}
+27 -15
View File
@@ -1,6 +1,6 @@
<template>
<div class="settings-container">
<div class="loading" :class="firstLoading ? 'loading-show' : 'loading-hide'" >
<div class="loading" :class="firstLoading ? 'loading-show' : 'loading-hide'">
<loading/>
</div>
<el-scrollbar class="scroll" v-if="!firstLoading">
@@ -209,6 +209,14 @@
</el-button>
</div>
</div>
<div class="setting-item">
<div><span>{{ $t('S3配置') }}</span></div>
<div class="r2domain">
<el-button class="opt-button" size="small" type="primary" @click="ossConfigShow = true">
<Icon icon="fluent:settings-48-regular" width="18" height="18"/>
</el-button>
</div>
</div>
</div>
</div>
@@ -347,20 +355,20 @@
</div>
<div class="concerning-item">
<span>{{ $t('community') }} : </span>
<div class="community">
<el-button @click="jump('https://github.com/eoao/cloud-mail')">
Github
<template #icon>
<Icon icon="codicon:github-inverted" width="22" height="22"/>
</template>
</el-button>
<el-button @click="jump('https://t.me/cloud_mail_tg')">
Telegram
<template #icon>
<Icon icon="logos:telegram" width="30" height="30"/>
</template>
</el-button>
</div>
<div class="community">
<el-button @click="jump('https://github.com/eoao/cloud-mail')">
Github
<template #icon>
<Icon icon="codicon:github-inverted" width="22" height="22"/>
</template>
</el-button>
<el-button @click="jump('https://t.me/cloud_mail_tg')">
Telegram
<template #icon>
<Icon icon="logos:telegram" width="30" height="30"/>
</template>
</el-button>
</div>
</div>
<div class="concerning-item">
<span>{{ $t('support') }} : </span>
@@ -672,6 +680,7 @@ const userStore = useUserStore();
const editTitleShow = ref(false)
const resendTokenFormShow = ref(false)
const r2DomainShow = ref(false)
const ossConfigShow = ref(false)
const turnstileShow = ref(false)
const tgSettingShow = ref(false)
const noticePopupShow = ref(false)
@@ -1173,6 +1182,7 @@ function editSetting(settingForm, refreshStatus = true) {
overflow: hidden;
background: var(--extra-light-fill) !important;
position: relative;
.loading {
display: flex;
align-items: center;
@@ -1522,9 +1532,11 @@ function editSetting(settingForm, refreshStatus = true) {
row-gap: 10px;
flex-wrap: wrap;
}
:deep(.el-button) {
padding: 0 10px;
font-weight: normal;
i {
font-size: 22px;
}
+52 -29
View File
@@ -1,37 +1,60 @@
import {defineConfig,loadEnv} from 'vite'
import {defineConfig, loadEnv} from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import {ElementPlusResolver} from 'unplugin-vue-components/resolvers'
import {VitePWA} from 'vite-plugin-pwa';
export default defineConfig(({mode}) => {
const env = loadEnv(mode, process.cwd(), 'VITE')
return {
server: {
host: true,
port: 3001,
hmr: true,
},
base: env.VITE_STATIC_URL || '/',
plugins: [vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
})
],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
},
build: {
target: 'es2022',
outDir: env.VITE_OUT_DIR || 'dist',
emptyOutDir: true,
assetsInclude: ['**/*.json']
const env = loadEnv(mode, process.cwd(), 'VITE')
return {
server: {
host: true,
port: 3001,
hmr: true,
},
base: env.VITE_STATIC_URL || '/',
plugins: [vue(),
VitePWA({
registerType: 'autoUpdate', // 配置 service worker 的注册方式
includeAssets: ['favicon.svg', 'robots.txt'], // 指定需要包含的静态资源
manifest: {
name: 'Cloud Mail',
short_name: 'Cloud Mail',
background_color: '#FFFFFF',
theme_color: '#FFFFFF',
icons: [
{
src: 'mail-192.png',//像素尺寸一定要对应
sizes: '192x192',
type: 'image/png',
},
{
src: 'mail-512.png',
sizes: '512x512',
type: 'image/png',
},
],
},
}),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
})
],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
},
build: {
target: 'es2022',
outDir: env.VITE_OUT_DIR || 'dist',
emptyOutDir: true,
assetsInclude: ['**/*.json']
}
}
}
})