Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions src/i18n/message/app/option-resource.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
"popup": {
"title": "弹窗页",
"max": "只显示前 {input} 条数据,剩下的条目合并显示",
"defaultMergeMethod": "默认数据合并方式 {input}",
"defaultDisplay": "打开时显示 {duration} {type}",
"displaySiteName": "{input} 显示时是否使用 {siteName} 来代替域名"
},
"appearance": {
Expand Down Expand Up @@ -136,8 +134,6 @@
"popup": {
"title": "彈出視窗",
"max": "僅顯示前 {input} 筆資料,其餘項目合併",
"defaultMergeMethod": "預設資料合併方式 {input}",
"defaultDisplay": "開啟時顯示 {duration} {type}",
"displaySiteName": "{input} 是否使用 {siteName} 取代網域"
},
"appearance": {
Expand Down Expand Up @@ -266,8 +262,6 @@
"popup": {
"title": "Popup Page",
"max": "Show the first {input} data items",
"defaultMergeMethod": "Default data merging method {input}",
"defaultDisplay": "Show {duration} {type} on open",
"displaySiteName": "{input} Whether to display {siteName} instead of URL"
},
"appearance": {
Expand Down Expand Up @@ -397,8 +391,6 @@
"popup": {
"title": "ポップアップページ",
"max": "最初の {input} 個のデータのみを表示し、残りのエントリは結合されます",
"defaultMergeMethod": "デフォルトのデータマージ方法 {input}",
"defaultDisplay": "開くと {duration} {type} が表示されます",
"displaySiteName": "{input} ホストの代わりに {siteName} を表示するかどうか"
},
"appearance": {
Expand Down Expand Up @@ -527,8 +519,6 @@
"popup": {
"title": "Página de Pop-up",
"max": "Mostrar os primeiros {input} itens de dados",
"defaultMergeMethod": "Método padrão de fusão de dados {input}",
"defaultDisplay": "Mostrar {type} de {duration} em aberto",
"displaySiteName": "{input} Se deve exibir {siteName} em vez de URL"
},
"appearance": {
Expand Down Expand Up @@ -656,8 +646,6 @@
"popup": {
"title": "Вікно розширення",
"max": "Кількість записів для показу: {input}",
"defaultMergeMethod": "Метод злиття даних за замовчуванням {input}",
"defaultDisplay": "Дані для показу: {duration} {type}",
"displaySiteName": "{input} Показувати {siteName} замість URL-адреси"
},
"appearance": {
Expand Down Expand Up @@ -786,8 +774,6 @@
"popup": {
"title": "Página emergente",
"max": "Mostrar los primeros {input} elementos de datos",
"defaultMergeMethod": "Método de fusión de datos predeterminado {input}",
"defaultDisplay": "Mostrar {duration} {type} al abrir",
"displaySiteName": "{input} Mostrar {siteName} en lugar de la URL"
},
"appearance": {
Expand Down Expand Up @@ -915,8 +901,6 @@
"popup": {
"title": "Popup-Seite",
"max": "Zeige die ersten {input} Datenelemente",
"defaultMergeMethod": "Standardmethode zum Zusammenführen von Daten {input}",
"defaultDisplay": "{duration} {type} beim Öffnen anzeigen",
"displaySiteName": "{input} {siteName} statt URL anzeigen"
},
"appearance": {
Expand Down Expand Up @@ -1041,8 +1025,6 @@
"popup": {
"title": "Page pop-up",
"max": "Afficher les {input} premiers éléments de données",
"defaultMergeMethod": "Méthode de fusion des données par défaut {input}",
"defaultDisplay": "Afficher {duration} {type} à l'ouverture",
"displaySiteName": "{input} S'il faut afficher {siteName} au lieu de l'URL"
},
"appearance": {
Expand Down Expand Up @@ -1167,7 +1149,6 @@
"popup": {
"title": "Всплывающее окно",
"max": "Показать первые {input} элементов данных",
"defaultDisplay": "Показать {duration} {type} при открытии",
"displaySiteName": "{input} Отображать ли {siteName} вместо URL"
},
"appearance": {
Expand Down
2 changes: 0 additions & 2 deletions src/i18n/message/app/option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ export type OptionMessage = {
popup: {
title: string
max: string
defaultMergeMethod: string
defaultDisplay: string
displaySiteName: string
}
appearance: {
Expand Down
82 changes: 1 addition & 81 deletions src/pages/app/components/Option/components/PopupOption.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,54 +5,18 @@
* https://opensource.org/licenses/MIT
*/
import { t } from "@app/locale"
import { type I18nKey, t as t_ } from "@i18n"
import DurationSelect, { rangeLabel } from "@popup/components/Footer/DurationSelect"
import { IS_ANDROID } from "@util/constant/environment"
import { defaultPopup } from "@util/constant/option"
import { ALL_DIMENSIONS } from "@util/stat"
import { ElInputNumber, ElOption, ElSelect, ElSwitch } from "element-plus"
import { ElInputNumber, ElSwitch } from "element-plus"
import { defineComponent } from "vue"
import { type OptionInstance } from "../common"
import { useOption } from "../useOption"
import OptionItem from "./OptionItem"
import OptionTag from "./OptionTag"

type LocaleStyle = {
/**
* Width of duration select
*/
duration: number
/**
* Width and type select
*/
type: number
}

const STYLES: Messages<LocaleStyle> = {
zh_CN: { type: 85, duration: 100 },
en: { type: 115, duration: 110 },
ja: { type: 85, duration: 110 },
pt_PT: { type: 155, duration: 120 },
zh_TW: { type: 85, duration: 100 },
uk: { type: 145, duration: 120 },
es: { type: 160, duration: 125 },
de: { duration: 120 },
fr: { type: 150, duration: 130 },
ru: { type: 170, duration: 150 },
}

const tStyle = (key: I18nKey<LocaleStyle>) => t_(STYLES, { key })

const defaultPopOptions = defaultPopup()
const defaultTypeLabel = t(msg => msg.item[defaultPopOptions.defaultType])
const defaultDurationLabel = rangeLabel(defaultPopOptions.defaultDuration, defaultPopOptions.defaultDurationNum)
const displayDefaultLabel = `${defaultDurationLabel}/${defaultTypeLabel}`

function copy(target: timer.option.PopupOption, source: timer.option.PopupOption) {
target.defaultMergeMethod = source.defaultMergeMethod
target.defaultDuration = source.defaultDuration
target.defaultDurationNum = source.defaultDurationNum
target.defaultType = source.defaultType
target.displaySiteName = source.displaySiteName
target.popupMax = source.popupMax
}
Expand All @@ -66,51 +30,7 @@ const _default = defineComponent((_props, ctx) => {

return () => <>
<OptionItem
label={msg => msg.option.popup.defaultMergeMethod}
defaultValue={t(msg => msg.shared.merge.mergeMethod.notMerge)}
hideDivider
>
<ElSelect
size="small"
modelValue={option.defaultMergeMethod}
placeholder={t(msg => msg.shared.merge.mergeMethod.notMerge)}
onChange={(val: timer.stat.MergeMethod) => option.defaultMergeMethod = val || undefined}
>
<ElOption value={''} label={t(msg => msg.shared.merge.mergeMethod.notMerge)} />
{(['domain', 'cate'] satisfies timer.stat.MergeMethod[]).map(m => (
<ElOption value={m} label={t(msg => msg.shared.merge.mergeMethod[m])} />
))}
</ElSelect>
</OptionItem>
<OptionItem
label={msg => msg.option.popup.defaultDisplay}
defaultValue={displayDefaultLabel}
v-slots={{
duration: () => (
<DurationSelect
size="small"
expandTrigger="hover"
modelValue={[option.defaultDuration, option.defaultDurationNum]}
onChange={([duration, num]) => {
option.defaultDuration = duration
option.defaultDurationNum = num
}}
style={{ width: `${tStyle(m => m.duration)}px` }}
/>
),
type: () => (
<ElSelect
modelValue={option.defaultType}
size="small"
style={{ width: `${tStyle(m => m.type)}px` }}
onChange={(val: timer.core.Dimension) => option.defaultType = val}
>
{ALL_DIMENSIONS.map(item => <ElOption value={item} label={t(msg => msg.item[item])} />)}
</ElSelect>
)
}}
/>
<OptionItem
label={msg => msg.option.popup.max}
defaultValue={defaultPopOptions.popupMax}
>
Expand Down
14 changes: 2 additions & 12 deletions src/pages/popup/Main.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
import Flex from "@pages/components/Flex"
import { DefaultOption } from "@util/constant/option"
import { defineComponent, inject } from "vue"
import { defineComponent } from "vue"
import { RouterView } from "vue-router"
import Footer from "./components/Footer"
import Header from "./components/Header"
import { initPopupContext } from "./context"

export const PROVIDE_KEY = 'POPUP_OPTION'

const Main = defineComponent(() => {
const option = inject(PROVIDE_KEY) as DefaultOption
const { defaultDuration, defaultType, defaultDurationNum, defaultMergeMethod } = option

const appKey = initPopupContext({
mergeMethod: defaultMergeMethod,
duration: defaultDuration,
type: defaultType,
durationNum: defaultDurationNum,
})
const appKey = initPopupContext()

return () => (
<Flex key={appKey.value} column width='100%' height='100%' gap={10}>
Expand Down
12 changes: 3 additions & 9 deletions src/pages/popup/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@ import { type StatQueryParam } from "@service/stat-service"
import { isRemainHost } from "@util/constant/remain-host"
import { getAppPageUrl } from "@util/constant/url"
import { getMonthTime, MILL_PER_DAY } from "@util/time"

export type PopupQuery = {
mergeMethod: timer.stat.MergeMethod | undefined
duration: timer.option.PopupDuration
durationNum?: number
type: timer.core.Dimension
}
import { type PopupQuery } from "./context"

type DateRangeCalculator = (now: Date, num?: number) => Awaitable<Date | [Date, Date] | undefined>

Expand All @@ -28,12 +22,12 @@ const DATE_RANGE_CALCULATORS: { [duration in timer.option.PopupDuration]: DateRa
}

export const cvt2StatQuery = async (param: PopupQuery): Promise<StatQueryParam> => {
const { duration, durationNum, mergeMethod, type } = param
const { duration, durationNum, mergeMethod, dimension } = param
const stat: StatQueryParam = {
date: await DATE_RANGE_CALCULATORS[duration]?.(new Date(), durationNum),
mergeHost: mergeMethod === 'domain',
mergeCate: mergeMethod === 'cate',
sort: type,
sort: dimension,
sortOrder: 'DESC',
mergeDate: true,
exclusiveVirtual: true,
Expand Down
84 changes: 37 additions & 47 deletions src/pages/popup/components/Footer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import Flex from "@pages/components/Flex"
import { type PopupQuery } from "@popup/common"
import DurationSelect from "@popup/components/Footer/DurationSelect"
import { usePopupContext } from "@popup/context"
import { t } from "@popup/locale"
Expand All @@ -8,58 +7,49 @@ import { ElOption, ElSelect, ElText } from "element-plus"
import { defineComponent } from "vue"
import Menu from "./Menu"

const Footer = defineComponent({
props: {
total: String,
},
setup() {
const { query, setQuery } = usePopupContext()
const Footer = defineComponent(() => {
const { query } = usePopupContext()

const updateQuery = <K extends keyof PopupQuery>(k: K, v: PopupQuery[K]) => {
setQuery({ ...query.value, [k]: v } satisfies PopupQuery)
}

return () => (
<Flex
justify="space-between"
width="100%"
>
<Flex>
<Menu />
</Flex>
<Flex gap={8}>
<Flex gap={4}>
<ElText>{t(msg => msg.shared.merge.mergeBy)}</ElText>
<ElSelect
modelValue={query.value?.mergeMethod}
onChange={(val: timer.stat.MergeMethod) => updateQuery('mergeMethod', val || undefined)}
placeholder={t(msg => msg.shared.merge.mergeMethod.notMerge)}
popperOptions={{ placement: 'top' }}
style={{ width: '90px' }}
>
<ElOption value='' label={t(msg => msg.shared.merge.mergeMethod.notMerge)} />
{(['domain', 'cate'] satisfies timer.stat.MergeMethod[]).map(method => (
<ElOption value={method} label={t(msg => msg.shared.merge.mergeMethod[method])} />
))}
</ElSelect>
</Flex>
<DurationSelect
reverse
modelValue={[query.value?.duration, query.value?.durationNum]}
onChange={([duration, durationNum]) => setQuery({ ...query.value, duration, durationNum })}
/>
return () => (
<Flex justify="space-between" width="100%">
<Flex>
<Menu />
</Flex>
<Flex gap={8}>
<Flex gap={4}>
<ElText>{t(msg => msg.shared.merge.mergeBy)}</ElText>
<ElSelect
modelValue={query?.value?.type}
onChange={(v: timer.core.Dimension) => updateQuery('type', v)}
modelValue={query.mergeMethod}
onChange={v => query.mergeMethod = v}
placeholder={t(msg => msg.shared.merge.mergeMethod.notMerge)}
popperOptions={{ placement: 'top' }}
style={{ width: '120px' }}
style={{ width: '90px' }}
>
{ALL_DIMENSIONS.map(item => <ElOption value={item} label={t(msg => msg.item[item])} />)}
<ElOption value='' label={t(msg => msg.shared.merge.mergeMethod.notMerge)} />
{(['domain', 'cate'] satisfies timer.stat.MergeMethod[]).map(method => (
<ElOption value={method} label={t(msg => msg.shared.merge.mergeMethod[method])} />
))}
</ElSelect>
</Flex>
</Flex >
)
}
<DurationSelect
reverse
modelValue={[query.duration, query.durationNum]}
onChange={([duration, durationNum]) => {
query.duration = duration
query.durationNum = durationNum
}}
/>
<ElSelect
modelValue={query.dimension}
onChange={v => query.dimension = v}
popperOptions={{ placement: 'top' }}
style={{ width: '120px' }}
>
{ALL_DIMENSIONS.map(item => <ElOption value={item} label={t(msg => msg.item[item])} />)}
</ElSelect>
</Flex>
</Flex >
)
})

export default Footer
Loading