diff --git a/src/common/constants/store.key.ts b/src/common/constants/store.key.ts index 1a8eb2acf..165d53aa1 100644 --- a/src/common/constants/store.key.ts +++ b/src/common/constants/store.key.ts @@ -14,8 +14,7 @@ import type { FetchedWeather, WeatherSettings, } from '@/layouts/widgets/weather/weather.interface' -import type { ClockSettings } from '@/layouts/widgets/wigi-pad/clock-display/clock-setting.interface' -import type { WigiPadDateSetting } from '@/layouts/widgets/wigi-pad/date-display/date-setting.interface' +import type { ClockSettings } from '@/layouts/widgets/clock/clock-setting.interface' import type { ExtensionConfigResponse } from '@/services/config-data/config-data.api' import type { FetchedCurrency } from '@/services/hooks/currency/get-currency-by-code.hook' import type { RecommendedSite, TrendItem } from '@/services/hooks/trends/get-trends.hook' @@ -65,7 +64,6 @@ export interface StorageKV { recent_searches: any pets: PetSettings clock: ClockSettings - wigiPadDate: WigiPadDateSetting configData: ExtensionConfigResponse toolsTab: ToolsTabType comboTabs: ComboTabType diff --git a/src/common/utils/call-event.ts b/src/common/utils/call-event.ts index 4a9d8403b..b340939c0 100644 --- a/src/common/utils/call-event.ts +++ b/src/common/utils/call-event.ts @@ -3,8 +3,7 @@ import type { Bookmark } from '@/layouts/bookmark/types/bookmark.types' import type { PetBackgroundId, PetTypes } from '@/layouts/widgets/pet/types' import type { WigiNewsSetting } from '@/layouts/widgets/news/rss.interface' import type { WeatherSettings } from '@/layouts/widgets/weather/weather.interface' -import type { ClockSettings } from '@/layouts/widgets/wigi-pad/clock-display/clock-setting.interface' -import type { WigiPadDateSetting } from '@/layouts/widgets/wigi-pad/date-display/date-setting.interface' +import type { ClockSettings } from '@/layouts/widgets/clock/clock-setting.interface' import type { WidgetTabKeys } from '@/layouts/widgets-settings/tab-keys' import type { StoredWallpaper, Wallpaper } from '../wallpaper.interface' import type { Todo } from '@/services/hooks/todo/todo.interface' @@ -54,8 +53,7 @@ export interface EventName { } // setting keys - wigiPadDateSettingsChanged: WigiPadDateSetting - wigiPadClockSettingsChanged: ClockSettings + clockSettingsChanged: ClockSettings currencies_updated: { currencies: string[] colorMode: CurrencyColorMode diff --git a/src/layouts/widgets-settings/tab-keys.ts b/src/layouts/widgets-settings/tab-keys.ts index 2cf0b7e75..9593a1715 100644 --- a/src/layouts/widgets-settings/tab-keys.ts +++ b/src/layouts/widgets-settings/tab-keys.ts @@ -1,6 +1,5 @@ export enum WidgetTabKeys { widget_management = 'widget_management', - wigiPad = 'wigiPad', wigiArz = 'wigiArz', news_settings = 'news_settings', weather_settings = 'weather_settings', diff --git a/src/layouts/widgets-settings/widget-settings-modal.tsx b/src/layouts/widgets-settings/widget-settings-modal.tsx index e52503ed5..966efde21 100644 --- a/src/layouts/widgets-settings/widget-settings-modal.tsx +++ b/src/layouts/widgets-settings/widget-settings-modal.tsx @@ -4,7 +4,6 @@ import { PetSettings } from '../widgets/pet/pet-setting' import { RssFeedSetting } from '../widgets/news/rss-feed-setting' import { WeatherSetting } from '../widgets/weather/weather-setting' import { WigiArzSetting } from '../widgets/wigi-arz/wigi-arz-setting' -import { WigiPadSetting } from '../widgets/wigi-pad/wigi-pad-setting' import { ComboSetting } from '../widgets/combo-widget/combo-setting' import { WidgetTabKeys } from './tab-keys' @@ -35,11 +34,6 @@ const WIDGET_SETTING_MODALS: Record = { size: 'lg', Component: RssFeedSetting, }, - [WidgetTabKeys.wigiPad]: { - title: 'تنظیمات ویجی پد', - size: 'lg', - Component: WigiPadSetting, - }, [WidgetTabKeys.combo_settings]: { title: 'تنظیمات ویجت ترکیبی', size: 'lg', diff --git a/src/layouts/widgets/__tests__/migration.test.ts b/src/layouts/widgets/__tests__/migration.test.ts index ab78e5184..8d52efc71 100644 --- a/src/layouts/widgets/__tests__/migration.test.ts +++ b/src/layouts/widgets/__tests__/migration.test.ts @@ -73,7 +73,7 @@ describe('migrateWidgetLayoutIfNeeded', () => { it('migrates classic layout using activeWidgets with custom order', async () => { storageMockData.appearance = { ui: 'CLASSIC' } storageMockData.activeWidgets = [ - { id: WidgetKeys.weather, order: 2 }, + { id: WidgetKeys.todos, order: 2 }, { id: WidgetKeys.calendar, order: 1 }, { id: 'unknown-widget', order: 0 }, ] @@ -83,7 +83,9 @@ describe('migrateWidgetLayoutIfNeeded', () => { expect(validateLayout(result, 8)).toBe(true) const topWidgetKeys = [ - WidgetKeys.wigiPad, + WidgetKeys.clock, + WidgetKeys.moodTracker, + WidgetKeys.weather, WidgetKeys.search, WidgetKeys.bookmarks, WidgetKeys.photo, @@ -96,7 +98,7 @@ describe('migrateWidgetLayoutIfNeeded', () => { const bottomWidgets = result.filter((w) => !topWidgetKeys.includes(w.id)) expect(bottomWidgets.map((w) => w.id)).toEqual([ WidgetKeys.calendar, - WidgetKeys.weather, + WidgetKeys.todos, ]) expect(storageMockData.appearance.ui).toBe('CUSTOM') diff --git a/src/layouts/widgets/wigi-pad/clock-display/clock-setting.interface.ts b/src/layouts/widgets/clock/clock-setting.interface.ts similarity index 99% rename from src/layouts/widgets/wigi-pad/clock-display/clock-setting.interface.ts rename to src/layouts/widgets/clock/clock-setting.interface.ts index 72c3c2c64..4dbce451f 100644 --- a/src/layouts/widgets/wigi-pad/clock-display/clock-setting.interface.ts +++ b/src/layouts/widgets/clock/clock-setting.interface.ts @@ -4,6 +4,7 @@ export interface ClockSettings { showTimeZone: boolean useSelectedFont: boolean } + export enum ClockType { Analog = 'analog', Digital = 'digital', diff --git a/src/layouts/widgets/clock/clock.widget.tsx b/src/layouts/widgets/clock/clock.widget.tsx index 3d107dede..568e1c8ac 100644 --- a/src/layouts/widgets/clock/clock.widget.tsx +++ b/src/layouts/widgets/clock/clock.widget.tsx @@ -6,7 +6,7 @@ import type { FetchedTimezone } from '@/services/hooks/timezone/get-timezones.ho import { type ClockSettings, ClockType, -} from '../wigi-pad/clock-display/clock-setting.interface' +} from './clock-setting.interface' import { WidgetContainer } from '../widget-container' import type { WidgetSize } from '../layout-engine/types' import { Clock1x1 } from './variants/clock-1x1' @@ -41,7 +41,7 @@ export function ClockWidget({ size = { w: 2, h: 1 }, meta }: ClockWidgetProps) { } } - const event = listenEvent('wigiPadClockSettingsChanged', (data) => { + const event = listenEvent('clockSettingsChanged', (data) => { setClockSettings({ clockType: data.clockType, showSeconds: data.showSeconds, diff --git a/src/layouts/widgets/layout-engine/__tests__/layout-engine.test.ts b/src/layouts/widgets/layout-engine/__tests__/layout-engine.test.ts index 40c83942c..aab012945 100644 --- a/src/layouts/widgets/layout-engine/__tests__/layout-engine.test.ts +++ b/src/layouts/widgets/layout-engine/__tests__/layout-engine.test.ts @@ -92,8 +92,8 @@ describe('Layout Engine Tests', () => { size: { w: 4, h: 2 }, }, { - id: WidgetKeys.wigiPad, - instanceId: 'wigipad', + id: WidgetKeys.clock, + instanceId: 'clock', position: { col: 0, row: 3 }, size: { w: 2, h: 2 }, }, @@ -102,7 +102,7 @@ describe('Layout Engine Tests', () => { const result = resolveLayoutChange({ layout: initial, operation: 'move', - instanceId: 'wigipad', + instanceId: 'clock', targetPosition: { col: 0, row: 0 }, cols: 8, }) @@ -110,8 +110,8 @@ describe('Layout Engine Tests', () => { expect(result).not.toBeNull() expect(validateLayout(result!, 8)).toBe(true) - const wigipad = result!.find((w) => w.instanceId === 'wigipad')! - expect(wigipad.position).toEqual({ col: 0, row: 0 }) + const clock = result!.find((w) => w.instanceId === 'clock')! + expect(clock.position).toEqual({ col: 0, row: 0 }) }) it('compacts layout removing vertical gaps', () => { @@ -149,14 +149,16 @@ describe('Layout Engine Tests', () => { expect(slot).toEqual({ col: 0, row: 1 }) }) - it('contains 9 widgets in the default layout matching the Advanced layout', () => { - expect(DEFAULT_WIDGET_LAYOUT.length).toBe(9) + it('contains 11 widgets in the default layout matching the Advanced layout', () => { + expect(DEFAULT_WIDGET_LAYOUT.length).toBe(11) const widgetIds = DEFAULT_WIDGET_LAYOUT.map((w) => w.id) expect(widgetIds).toContain(WidgetKeys.photo) expect(widgetIds).toContain(WidgetKeys.pet) expect(widgetIds).toContain(WidgetKeys.search) expect(widgetIds).toContain(WidgetKeys.bookmarks) - expect(widgetIds).toContain(WidgetKeys.wigiPad) + expect(widgetIds).toContain(WidgetKeys.clock) + expect(widgetIds).toContain(WidgetKeys.moodTracker) + expect(widgetIds).toContain(WidgetKeys.weather) expect(widgetIds).toContain(WidgetKeys.calendar) expect(widgetIds).toContain(WidgetKeys.yadKar) expect(widgetIds).toContain(WidgetKeys.tools) @@ -172,11 +174,10 @@ describe('Layout Engine Tests', () => { size: { w: 4, h: 1 }, }, { - id: WidgetKeys.wigiPad, - instanceId: 'wigipad-default', + id: WidgetKeys.clock, + instanceId: 'clock-default', position: { col: 0, row: 3 }, - size: { w: 2, h: 4 }, - meta: { variant: 'simplify' }, + size: { w: 2, h: 2 }, }, { id: WidgetKeys.bookmarks, diff --git a/src/layouts/widgets/layout-engine/constants.ts b/src/layouts/widgets/layout-engine/constants.ts index 6b35b480e..b898bcc53 100644 --- a/src/layouts/widgets/layout-engine/constants.ts +++ b/src/layouts/widgets/layout-engine/constants.ts @@ -38,10 +38,23 @@ export const GRID_BREAKPOINTS: GridBreakpoint[] = [ export const DEFAULT_WIDGET_LAYOUT: StoredWidget[] = [ { - id: WidgetKeys.wigiPad, - instanceId: 'wigipad-default', + id: WidgetKeys.clock, + instanceId: 'clock-default', position: { col: 0, row: 0 }, - size: { w: 2, h: 3 }, + size: { w: 2, h: 1 }, + meta: { variant: 'digital' }, + }, + { + id: WidgetKeys.moodTracker, + instanceId: 'moodtracker-default', + position: { col: 0, row: 1 }, + size: { w: 2, h: 1 }, + }, + { + id: WidgetKeys.weather, + instanceId: 'weather-default', + position: { col: 0, row: 2 }, + size: { w: 2, h: 1 }, }, { id: WidgetKeys.search, diff --git a/src/layouts/widgets/layout-engine/types.ts b/src/layouts/widgets/layout-engine/types.ts index 8fefeb63d..694c343ef 100644 --- a/src/layouts/widgets/layout-engine/types.ts +++ b/src/layouts/widgets/layout-engine/types.ts @@ -7,7 +7,6 @@ export enum WidgetKeys { todos = 'todos', tools = 'tools', notes = 'notes', - wigiPad = 'wigiPad', network = 'network', yadKar = 'yadKar', HabitTracker = 'HabitTracker', diff --git a/src/layouts/widgets/migration.ts b/src/layouts/widgets/migration.ts index bd2160b11..e03bf5062 100644 --- a/src/layouts/widgets/migration.ts +++ b/src/layouts/widgets/migration.ts @@ -11,10 +11,23 @@ const DEFAULT_BOTTOM_WIDGETS: WidgetKeys[] = [ const topWidgets: StoredWidget[] = [ { - id: WidgetKeys.wigiPad, - instanceId: 'wigipad-default', + id: WidgetKeys.clock, + instanceId: 'clock-default', position: { col: 0, row: 0 }, - size: { w: 2, h: 3 }, + size: { w: 2, h: 1 }, + meta: { variant: 'digital' }, + }, + { + id: WidgetKeys.moodTracker, + instanceId: 'moodtracker-default', + position: { col: 0, row: 1 }, + size: { w: 2, h: 1 }, + }, + { + id: WidgetKeys.weather, + instanceId: 'weather-default', + position: { col: 0, row: 2 }, + size: { w: 2, h: 1 }, }, { id: WidgetKeys.search, @@ -127,7 +140,7 @@ export async function migrateWidgetLayoutIfNeeded(): Promise { const bottomWidgets: StoredWidget[] = bottomKeys.map((key, index) => ({ id: key, - instanceId: `${key}-default`, + instanceId: `${key}-bottom-${index}`, position: { col: (index % 4) * 2, row: 3 + Math.floor(index / 4) * 3, diff --git a/src/layouts/widgets/presets/preset-layouts.ts b/src/layouts/widgets/presets/preset-layouts.ts index 06378fa11..aa737beaa 100644 --- a/src/layouts/widgets/presets/preset-layouts.ts +++ b/src/layouts/widgets/presets/preset-layouts.ts @@ -11,10 +11,23 @@ export const PRESET_LAYOUTS: PresetLayout[] = [ category: 'daily', widgets: [ { - id: WidgetKeys.wigiPad, - instanceId: 'wigipad-default', + id: WidgetKeys.clock, + instanceId: 'clock-default', position: { col: 0, row: 0 }, - size: { w: 2, h: 3 }, + size: { w: 2, h: 1 }, + meta: { variant: 'digital' }, + }, + { + id: WidgetKeys.moodTracker, + instanceId: 'moodtracker-default', + position: { col: 0, row: 1 }, + size: { w: 2, h: 1 }, + }, + { + id: WidgetKeys.weather, + instanceId: 'weather-default', + position: { col: 0, row: 2 }, + size: { w: 2, h: 1 }, }, { id: WidgetKeys.search, diff --git a/src/layouts/widgets/widget-registry.tsx b/src/layouts/widgets/widget-registry.tsx index 0a4f35a87..118e6964a 100644 --- a/src/layouts/widgets/widget-registry.tsx +++ b/src/layouts/widgets/widget-registry.tsx @@ -8,7 +8,6 @@ import { NewsLayout } from '@/layouts/widgets/news/news.widget' import { ToolsLayout } from '@/layouts/widgets/tools/tools.widget' import { WeatherLayout } from '@/layouts/widgets/weather/weather.widget' import { WigiArzLayout } from '@/layouts/widgets/wigi-arz/wigi-arz.widget' -import { WigiPadWidget } from '@/layouts/widgets/wigi-pad/wigi-pad.widget' import { YadkarWidget } from '@/layouts/widgets/yadkar/yadkar.widget' import { HabitsLayout } from '@/layouts/widgets/habit/habit.widget' import { CurrencyProvider } from '@/context/currency.context' @@ -73,27 +72,6 @@ export const WIDGET_DEFINITIONS: Record = { ), }, - [WidgetKeys.wigiPad]: { - id: WidgetKeys.wigiPad, - label: 'ویجی‌پد', - emoji: '⏰', - category: 'time', - allowedSizes: [{ w: 2, h: 3 }], - defaultSize: { w: 2, h: 3 }, - settingsTab: WidgetTabKeys.wigiPad, - canDuplicate: false, - variants: [ - { - id: 'standard', - label: 'ویجی‌پد', - size: { w: 2, h: 3 }, - meta: { variant: 'standard' }, - }, - ], - node: (_instanceId, _size) => { - return - }, - }, [WidgetKeys.clock]: { id: WidgetKeys.clock, label: 'ساعت', @@ -222,7 +200,7 @@ export const WIDGET_DEFINITIONS: Record = { canToggle: true, allowedSizes: [ { w: 1, h: 1, isVipOnly: true }, - { w: 2, h: 1, isVipOnly: true }, + { w: 2, h: 1 }, { w: 2, h: 2, isVipOnly: true }, { w: 2, h: 3 }, ], diff --git a/src/layouts/widgets/wigi-pad/clock-display/clock-display.tsx b/src/layouts/widgets/wigi-pad/clock-display/clock-display.tsx deleted file mode 100644 index 31b5cf839..000000000 --- a/src/layouts/widgets/wigi-pad/clock-display/clock-display.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { useEffect, useState } from 'react' -import { getFromStorage } from '@/common/storage' -import { listenEvent } from '@/common/utils/call-event' -import { useGeneralSetting } from '@/context/general-setting.context' -import { type ClockSettings, ClockType } from './clock-setting.interface' -import { AnalogClock } from './clocks/analog-clock' -import { DigitalClock } from './clocks/digital-clock' - -export function ClockDisplay() { - const [clockSettings, setClockSettings] = useState(null) - const { selected_timezone: timezone } = useGeneralSetting() - - useEffect(() => { - async function load() { - const clockFromStore = await getFromStorage('clock') - if (clockFromStore) { - setClockSettings(clockFromStore) - } else { - setClockSettings({ - clockType: ClockType.Digital, - showSeconds: false, - showTimeZone: true, - useSelectedFont: true, - }) - } - } - - const event = listenEvent('wigiPadClockSettingsChanged', (data) => { - setClockSettings({ - clockType: data.clockType, - showSeconds: data.showSeconds, - showTimeZone: data.showTimeZone, - useSelectedFont: data.useSelectedFont, - }) - }) - - load() - - return () => { - event() - } - }, []) - - if (!clockSettings) { - return null - } - - return ( -
-
- {clockSettings.clockType === 'analog' ? ( - - ) : ( - - )} -
-
- ) -} diff --git a/src/layouts/widgets/wigi-pad/clock-display/clock-setting.tsx b/src/layouts/widgets/wigi-pad/clock-display/clock-setting.tsx deleted file mode 100644 index 38558e924..000000000 --- a/src/layouts/widgets/wigi-pad/clock-display/clock-setting.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import { useEffect, useState } from 'react' -import Analytics from '@/analytics' -import { getFromStorage, setToStorage } from '@/common/storage' -import { callEvent } from '@/common/utils/call-event' -import { CheckBoxWithDescription } from '@/components/ui' -import { ItemSelector } from '@/components/ui' -import { type ClockSettings, ClockType } from './clock-setting.interface' - -const CLOCK_OPTIONS = [ - { - key: 'digital', - label: 'ساعت دیجیتال', - description: 'نمایش ساعت به صورت عددی', - value: ClockType.Digital as const, - }, - { - key: 'analog', - label: 'ساعت آنالوگ', - description: 'نمایش ساعت به صورت عقربه‌ای', - value: ClockType.Analog as const, - }, -] - -export function ClockSetting() { - const [clockSettings, setClockSettings] = useState({ - clockType: ClockType.Digital, - showSeconds: false, - showTimeZone: true, - useSelectedFont: true, - }) - - useEffect(() => { - async function loadClock() { - const stored = await getFromStorage('clock') - if (stored) setClockSettings(stored) - } - loadClock() - }, []) - - const updateClockSettings = (updater: (prev: ClockSettings) => ClockSettings) => { - setClockSettings((prev) => { - const newSettings = updater(prev) - handleSave(newSettings) - return newSettings - }) - } - - const handleSave = async (settings: ClockSettings) => { - callEvent('wigiPadClockSettingsChanged', settings) - await setToStorage('clock', settings) - Analytics.event(`wigipad_clock_settings_${settings.clockType}_save`) - } - - const onSelectType = (type: ClockType) => { - updateClockSettings((prev) => ({ ...prev, clockType: type })) - } - - const onToggleSeconds = () => { - Analytics.event( - `wigipad_clock_settings_${!clockSettings.showSeconds ? 'enable' : 'disable'}_show_seconds` - ) - updateClockSettings((prev) => ({ ...prev, showSeconds: !prev.showSeconds })) - } - - const onToggleTimeZone = () => { - Analytics.event( - `wigipad_clock_settings_${!clockSettings.showTimeZone ? 'enable' : 'disable'}_show_time_zone` - ) - updateClockSettings((prev) => ({ ...prev, showTimeZone: !prev.showTimeZone })) - } - - const onToggleUseSelectedFont = () => { - Analytics.event( - `wigipad_clock_settings_${!clockSettings.useSelectedFont ? 'enable' : 'disable'}_use_selected_font` - ) - updateClockSettings((prev) => ({ - ...prev, - useSelectedFont: !prev.useSelectedFont, - })) - } - - return ( -
-
-

نوع نمایش ساعت را انتخاب کنید:

-
- {CLOCK_OPTIONS.map((option) => ( - onSelectType(option.value)} - label={option.label} - description={option.description} - className="flex-1 text-center" - /> - ))} -
-
- -
- - - - - -
-
- ) -} diff --git a/src/layouts/widgets/wigi-pad/clock-display/clocks/analog-clock.tsx b/src/layouts/widgets/wigi-pad/clock-display/clocks/analog-clock.tsx deleted file mode 100644 index 93adbfdce..000000000 --- a/src/layouts/widgets/wigi-pad/clock-display/clocks/analog-clock.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import type { FetchedTimezone } from '@/services/hooks/timezone/get-timezones.hook' -import type { ClockSettings } from '../clock-setting.interface' -import { useGeneralSetting } from '@/context/general-setting.context' -import { getTimeZoneLabel } from '@/common/utils/get-timezone-label' - -interface AnalogClockProps { - timezone: FetchedTimezone - setting: ClockSettings -} - -export function AnalogClock({ timezone, setting }: AnalogClockProps) { - const [time, setTime] = useState( - new Date(new Date().toLocaleString('en-US', { timeZone: timezone.value })) - ) - const { isOptimalMode } = useGeneralSetting() - - const showSeconds = setting.showSeconds && !isOptimalMode - - useEffect(() => { - const updateTime = () => { - setTime( - new Date( - new Date().toLocaleString('en-US', { - timeZone: timezone.value, - }) - ) - ) - } - - updateTime() - - const interval = showSeconds ? 1000 : 60_000 - - const timer = setInterval(updateTime, interval) - - return () => clearInterval(timer) - }, [timezone.value, showSeconds]) - - const hours = time.getHours() % 12 - const minutes = time.getMinutes() - const seconds = time.getSeconds() - - const handColor = 'currentColor' - const timezoneLabel = useMemo(() => getTimeZoneLabel(timezone?.label), [timezone]) - - const hourAngle = useMemo(() => hours * 30 + minutes * 0.5, [hours, minutes]) - const minuteAngle = useMemo(() => minutes * 6, [minutes]) - const secondAngle = useMemo(() => seconds * 6, [seconds]) - - const hourMarkers = useMemo(() => { - return Array.from({ length: 12 }, (_, i) => { - const angle = i * 30 - const isMain = i % 3 === 0 - const innerRadius = isMain ? 35 : 38 - const outerRadius = 85 - - const x1 = 60 + innerRadius * Math.cos(((angle - 90) * Math.PI) / 180) - const y1 = 60 + innerRadius * Math.sin(((angle - 90) * Math.PI) / 180) - const x2 = 60 + outerRadius * Math.cos(((angle - 90) * Math.PI) / 180) - const y2 = 60 + outerRadius * Math.sin(((angle - 90) * Math.PI) / 180) - - return { x1, y1, x2, y2, isMain } - }) - }, []) - - return ( -
-
- - {hourMarkers.map(({ x1, y1, x2, y2, isMain }, i) => ( - - ))} - - {/* Hour hand */} - - - {/* Minute hand */} - - - {/* Second hand */} - {setting.showSeconds && ( - <> - - - - )} - - - {/* Timezone label */} - {setting.showTimeZone && ( -
- - {timezoneLabel} - -
- )} -
-
- ) -} diff --git a/src/layouts/widgets/wigi-pad/clock-display/clocks/digital-clock.tsx b/src/layouts/widgets/wigi-pad/clock-display/clocks/digital-clock.tsx deleted file mode 100644 index 0c8bd7055..000000000 --- a/src/layouts/widgets/wigi-pad/clock-display/clocks/digital-clock.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import type { FetchedTimezone } from '@/services/hooks/timezone/get-timezones.hook' -import type { ClockSettings } from '../clock-setting.interface' -import { useGeneralSetting } from '@/context/general-setting.context' -import { getTimeZoneLabel } from '@/common/utils/get-timezone-label' - -interface DigitalClockProps { - timezone: FetchedTimezone - setting: ClockSettings -} -export function DigitalClock({ timezone, setting }: DigitalClockProps) { - const { isOptimalMode } = useGeneralSetting() - const [time, setTime] = useState( - new Date(new Date().toLocaleString('en-US', { timeZone: timezone.value })) - ) - - const showSeconds = setting.showSeconds && !isOptimalMode - - useEffect(() => { - const updateTime = () => { - setTime( - new Date( - new Date().toLocaleString('en-US', { - timeZone: timezone.value, - }) - ) - ) - } - - updateTime() - - const interval = showSeconds ? 1000 : 60_000 - - const timer = setInterval(updateTime, interval) - - return () => clearInterval(timer) - }, [timezone.value, showSeconds]) - - const hours = time.getHours().toString().padStart(2, '0') - const minutes = time.getMinutes().toString().padStart(2, '0') - const seconds = time.getSeconds().toString().padStart(2, '0') - - const textColor = 'text-content' - - const getFontTranslateClass = () => { - return setting.useSelectedFont - ? '-translate-y-[calc(50%+0.200rem)]' - : '-translate-y-[calc(50%+0.9rem)]' - } - - const digitalClockStyles = showSeconds - ? `inset-x-5 ${ - setting.showTimeZone - ? getFontTranslateClass() - : '-translate-y-[calc(50%+0.1rem)]' - } text-5xl` - : `${ - setting.showTimeZone - ? '-translate-y-[calc(50%+0.2rem)]' - : '-translate-y-[calc(50%)]' - } text-[3.4rem]` - - const clockWidth = showSeconds ? 'w-[calc(100%-2.8rem)]' : 'w-[calc(100%-2.5rem)]' - - const timeZoneStyles = showSeconds - ? 'inset-x-5 w-[calc(100%-2.5rem)] text-xs' - : 'translate-y-20 text-sm' - - const timezoneLabel = getTimeZoneLabel(timezone.label) - - const lines = useMemo(() => { - return [...Array(60)].map((_, i) => { - const side = Math.floor((i + 7) / 15) - let x1 = 0, - x2 = 0, - y1 = 0, - y2 = 0 - let differential: number - - switch (side) { - case 0: - differential = Math.tan(((i - 30) * 6 * Math.PI) / 180) - y1 = i === 7 ? 11 : 10 - x1 = 60 + differential * 50 - y2 = 0 - x2 = i !== 0 ? x1 + differential * 10 : x1 - break - case 1: - differential = Math.tan(((15 - i) * 6 * Math.PI) / 180) - x1 = 109 - y1 = 80 - differential * 70 - x2 = 120 - y2 = y1 - differential * 11 - break - case 2: - differential = Math.tan(((i - 30) * 6 * Math.PI) / 180) - x1 = 60 - differential * 50 - y1 = i === 23 || i === 37 ? 149 : 150 - x2 = x1 - differential * 10 - y2 = 160 - break - case 3: - differential = Math.tan(((i - 45) * 6 * Math.PI) / 180) - x1 = 11 - y1 = 80 - differential * 70 - x2 = 0 - y2 = y1 - differential * 11 - break - case 4: - differential = Math.tan(((i - 30) * 6 * Math.PI) / 180) - x1 = 60 + differential * 50 - y1 = i === 53 ? 11 : 10 - y2 = 0 - x2 = x1 + differential * 10 - break - } - return { x1, y1, x2, y2, index: i === 0 ? 60 : i } - }) - }, []) - - const opacities = useMemo(() => { - const intSeconds = Number.parseInt(seconds, 10) - return lines.map(({ index }) => { - return intSeconds - index >= 0 - ? (60 - Math.abs(intSeconds - 1 - index)) / 60 - : (index - intSeconds + 1) / 60 - }) - }, [seconds, lines]) - - return ( -
- {showSeconds ? ( - - {lines.map(({ x1, y1, x2, y2, index }, i) => ( - - ))} - - ) : null} - -
- {hours} - {minutes} -
- - {setting.showTimeZone && ( -
- {timezoneLabel} -
- )} -
- ) -} diff --git a/src/layouts/widgets/wigi-pad/date-display/date-display.tsx b/src/layouts/widgets/wigi-pad/date-display/date-display.tsx deleted file mode 100644 index ac0b74777..000000000 --- a/src/layouts/widgets/wigi-pad/date-display/date-display.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { getFromStorage } from '@/common/storage' -import { listenEvent } from '@/common/utils/call-event' -import { type WigiPadDateSetting, WigiPadDateType } from './date-setting.interface' -import { GregorianDate } from './dates/gregorian-date' -import { JalaliDate } from './dates/jalali-date' - -export function DateDisplay() { - const [wigiPadDateSettings, setWigiPadDateSettings] = - useState(null) - useEffect(() => { - async function load() { - const wigiPadDateFromStore = await getFromStorage('wigiPadDate') - if (wigiPadDateFromStore) { - setWigiPadDateSettings(wigiPadDateFromStore) - } else { - setWigiPadDateSettings({ - dateType: WigiPadDateType.Jalali, - }) - } - } - - const event = listenEvent('wigiPadDateSettingsChanged', (data) => { - setWigiPadDateSettings({ dateType: data.dateType }) - }) - - load() - - return () => { - event() - } - }, []) - - if (!wigiPadDateSettings) { - return null - } - - return ( -
- {wigiPadDateSettings.dateType === WigiPadDateType.Jalali ? ( - - ) : ( - - )} -
- ) -} diff --git a/src/layouts/widgets/wigi-pad/date-display/date-setting.interface.ts b/src/layouts/widgets/wigi-pad/date-display/date-setting.interface.ts deleted file mode 100644 index f68012acd..000000000 --- a/src/layouts/widgets/wigi-pad/date-display/date-setting.interface.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum WigiPadDateType { - Jalali = 'jalali', - Gregorian = 'gregorian', -} - -export interface WigiPadDateSetting { - dateType: WigiPadDateType -} diff --git a/src/layouts/widgets/wigi-pad/date-display/date-setting.tsx b/src/layouts/widgets/wigi-pad/date-display/date-setting.tsx deleted file mode 100644 index 4dc85d71c..000000000 --- a/src/layouts/widgets/wigi-pad/date-display/date-setting.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { useState } from 'react' -import Analytics from '@/analytics' -import { getFromStorage, setToStorage } from '@/common/storage' -import { callEvent } from '@/common/utils/call-event' -import { ItemSelector } from '@/components/ui' -import { WigiPadDateType } from './date-setting.interface' - -const DateOptions = [ - { - key: 'jalali', - label: 'هجری شمسی', - description: 'نمایش تاریخ به صورت هجری شمسی', - value: WigiPadDateType.Jalali as const, - }, - { - key: 'gregorian', - label: 'تقویم میلادی', - description: 'نمایش تاریخ به صورت میلادی', - value: WigiPadDateType.Gregorian as const, - }, -] - -export function WigiPadDateSettingsModal() { - const [selectedType, setSelectedType] = useState() - - useEffect(() => { - async function load() { - const wigiPadDateFromStore = await getFromStorage('wigiPadDate') - if (wigiPadDateFromStore) { - setSelectedType(wigiPadDateFromStore.dateType) - } else { - setSelectedType(WigiPadDateType.Jalali) - } - } - - load() - }, []) - - const onSelectType = async (type: WigiPadDateType) => { - await setToStorage('wigiPadDate', { dateType: type }) - setSelectedType(type) - callEvent('wigiPadDateSettingsChanged', { dateType: type }) - Analytics.event(`wigipad_date_settings_${selectedType}_save`) - } - - return ( -
-
-

نوع نمایش تاریخ را انتخاب کنید:

- -
- {DateOptions.map((option) => ( - onSelectType(option.value)} - label={option.label} - description={option.description} - className="flex-1 text-center" - /> - ))} -
-
-
- ) -} diff --git a/src/layouts/widgets/wigi-pad/date-display/dates/gregorian-date.tsx b/src/layouts/widgets/wigi-pad/date-display/dates/gregorian-date.tsx deleted file mode 100644 index c239fb0ab..000000000 --- a/src/layouts/widgets/wigi-pad/date-display/dates/gregorian-date.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { useGeneralSetting } from '@/context/general-setting.context' -import { getCurrentDate } from '@/layouts/widgets/calendar/utils/date-events' - -export function GregorianDate() { - const { selected_timezone: timezone } = useGeneralSetting() - const today = getCurrentDate(timezone.value) - - const textColor = 'text-content drop-shadow-md' - const date = today.locale('en') - return ( -
- - {date.format('dddd')} - -
- {date.format('DD')} -
-
- - {date.format('MMMM')} - -
- {date.format('YYYY')} -
-
-
- ) -} diff --git a/src/layouts/widgets/wigi-pad/date-display/dates/jalali-date.tsx b/src/layouts/widgets/wigi-pad/date-display/dates/jalali-date.tsx deleted file mode 100644 index b6c713f32..000000000 --- a/src/layouts/widgets/wigi-pad/date-display/dates/jalali-date.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { useGeneralSetting } from '@/context/general-setting.context' -import { combineAndSortEvents } from '@/layouts/widgets/tools/events/utils/combine-events' -import { useGetEvents } from '@/services/hooks/date/get-events.hook' -import { convertShamsiToHijri, getCurrentDate, hijriMonthNames } from '@/layouts/widgets/calendar/utils/date-events' -import { useGetWeatherByLatLon } from '@/services/hooks/weather/get-weather-by-lat-lon.hook' -import { InlineWeather } from '../../weather/simple-weather' - -export function JalaliDate() { - const { selected_timezone: timezone } = useGeneralSetting() - const today = getCurrentDate(timezone.value) - const { data: events } = useGetEvents() - const eventsForCalendar = events || { - gregorianEvents: [], - hijriEvents: [], - shamsiEvents: [], - } - const sortedEvents = combineAndSortEvents(eventsForCalendar, today.clone(), []) - const todayIsHoliday = today.day() === 5 - const isHoliday = sortedEvents.some((event) => event.isHoliday) || todayIsHoliday - - const textColor = 'text-content drop-shadow-md' - - const gregorianShort = today.doAsGregorian().format('D MMM') - - const hijriDate = convertShamsiToHijri(today) - const hijriRaw = `${hijriDate.iYear()}/${hijriDate.iMonth() + 1}/${hijriDate.iDate()}` - const [_, hijriMonth, hijriDateDay] = hijriRaw.split('/') - const hijriMonthName = hijriMonthNames[Number(hijriMonth) - 1] || hijriMonth - const { data: weather } = useGetWeatherByLatLon(false) - - return ( - <> - {isHoliday && ( -
-
- تعطیل -
-
- )} -
- - {today.locale('fa').format('dddd')} - -
- {today.jDate()} -
-
-
- {today.locale('fa').format('MMMM')}{' '} - - {today.locale('fa').format('YYYY')} - -
- - {gregorianShort} · - {hijriDateDay} {hijriMonthName} - - -
-
- - ) -} diff --git a/src/layouts/widgets/wigi-pad/info-panel/components/ann-item.tsx b/src/layouts/widgets/wigi-pad/info-panel/components/ann-item.tsx deleted file mode 100644 index ae3dfd2e8..000000000 --- a/src/layouts/widgets/wigi-pad/info-panel/components/ann-item.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import Analytics from '@/analytics' -import { getContrastingTextColor } from '@/common/color' -import { callEvent } from '@/common/utils/call-event' -import type { NotificationItem } from '@/services/hooks/extension/get-notifications.hook' - -interface NotificationItemProps { - notification: NotificationItem -} - -interface Prop { - link: string | undefined - className: string - children: React.ReactNode - type: NotificationItem['type'] - target: NotificationItem['target'] - goTo: NotificationItem['goTo'] -} - -function Wrapper({ link, children, className, type, goTo, target }: Prop) { - const isClickable = !!link || ['page', 'action'].includes(type || '---') - - const handleClick = () => { - if (type === 'page' && goTo) { - callEvent('go_to_page', goTo as any) - Analytics.event('notifications_page') - } else if (type === 'action') { - callEvent(goTo as any, target as any) - Analytics.event('notifications_action') - } - } - - if (link) { - return ( - - {children} - - ) - } - - return ( -
- {children} -
- ) -} - -export function RenderWigiPadItem({ notification }: NotificationItemProps) { - const clickable = notification.link || notification.type !== 'text' - - const containerStyle: React.CSSProperties = { - backgroundColor: notification.backgroundColor || undefined, - borderRadius: notification.borderRadius || undefined, - } - - const titleStyle: React.CSSProperties = { - color: - notification.titleColor || notification.backgroundColor - ? getContrastingTextColor(notification.backgroundColor || '') - : undefined, - textDecoration: notification.titleDecoration, - } - - if (notification.type === 'banner') { - return ( - -
-
- ) - } - - return ( - -
- {notification.icon && ( -
- {notification?.icon.startsWith('http') || - notification?.icon.startsWith('/') ? ( - - ) : ( - {notification.icon} - )} -
- )} - -
-
- {notification.title} -
- - {notification.description && ( -
- {notification.description} -
- )} -
-
-
- ) -} diff --git a/src/layouts/widgets/wigi-pad/weather/simple-weather.tsx b/src/layouts/widgets/wigi-pad/weather/simple-weather.tsx deleted file mode 100644 index 062c10921..000000000 --- a/src/layouts/widgets/wigi-pad/weather/simple-weather.tsx +++ /dev/null @@ -1,36 +0,0 @@ -interface Prop { - weather: any - hasBanner: boolean -} -export function InlineWeather({ weather, hasBanner }: Prop) { - const temp = Math.round(weather?.weather?.temperature?.temp || 0) - const description = weather?.weather?.description?.text - let iconUrl: string | null = weather?.weather?.icon?.url - if (iconUrl?.includes('error')) { - iconUrl = null - } - - return ( -
-
- {iconUrl && ( - {description - )} -
- - {weather ? `${temp}°` : '–°'} - - - {description || 'آب‌وهوا'} - -
-
-
- ) -} diff --git a/src/layouts/widgets/wigi-pad/wigi-pad-setting.tsx b/src/layouts/widgets/wigi-pad/wigi-pad-setting.tsx deleted file mode 100644 index 7651c23e2..000000000 --- a/src/layouts/widgets/wigi-pad/wigi-pad-setting.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { SectionPanel } from '@/components/ui' -import { WidgetSettingWrapper } from '@/layouts/widgets-settings/widget-settings-wrapper' -import { ClockSetting } from './clock-display/clock-setting' -import { WigiPadDateSettingsModal } from './date-display/date-setting' - -export function WigiPadSetting() { - return ( - - - - - - - - - ) -} diff --git a/src/layouts/widgets/wigi-pad/wigi-pad.widget.tsx b/src/layouts/widgets/wigi-pad/wigi-pad.widget.tsx deleted file mode 100644 index 98499eb94..000000000 --- a/src/layouts/widgets/wigi-pad/wigi-pad.widget.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { WidgetContainer } from '../widget-container' -import { ClockDisplay } from './clock-display/clock-display' -import { DateDisplay } from './date-display/date-display' -import { useGetNotifications } from '@/services/hooks/extension/get-notifications.hook' -import { RenderWigiPadItem } from './info-panel/components/ann-item' - -export function WigiPadWidget() { - const { data: fetchedData } = useGetNotifications() - - return ( - -
- - -
-
-
- {fetchedData?.wigiPad.map((notification, index) => ( - - ))} -
-
-
- ) -}