├── .browserslistrc ├── .editorconfig ├── .eslintignore ├── .github └── workflows │ └── github-page.yml ├── .gitignore ├── LICENSE ├── README.md ├── auto-imports.d.ts ├── components.d.ts ├── eslint.config.js ├── index.html ├── package.json ├── public ├── audio │ ├── ding.mp3 │ ├── hangup.m4a │ ├── ringtone.m4a │ └── voice │ │ ├── elvis.mp3 │ │ ├── jackie_chan.wav │ │ ├── mrs_pan.m4a │ │ └── squidward.m4a ├── favicon.ico ├── firework │ ├── index.html │ ├── script.js │ └── style.css ├── font │ ├── SairaExtraCondensed-Regular.ttf │ ├── SairaExtraCondensed-Regular.woff │ └── SairaExtraCondensed-Regular.woff2 ├── images │ ├── avatar │ │ ├── elvis.png │ │ ├── international_friend.png │ │ ├── jackie_chan.jpg │ │ └── mrs_pan.jpg │ ├── preview_birthday_list.png │ ├── preview_clipboard.png │ ├── preview_countdown.png │ ├── preview_countdown2.png │ ├── preview_keystroke.png │ ├── preview_labor_progress.png │ ├── preview_lyric_book.png │ ├── preview_phone_reminder.png │ ├── preview_photo.png │ ├── preview_sit_reminder.png │ ├── preview_time_progress.png │ ├── preview_todo_list.png │ ├── preview_water_reminder.png │ ├── preview_wave_progress.png │ └── zhangyuge.jpg ├── screenshot.jpg └── widget.json ├── screenshot ├── dynamic_island.gif ├── labor_progress.gif ├── logo.png └── photo.png ├── src ├── App.vue ├── api │ ├── FeatureWallApi.ts │ ├── WebWidgetApi.ts │ └── axios.ts ├── assets │ ├── cancel.svg │ ├── css │ │ └── common.css │ ├── images │ │ ├── bilibili_logo_blue.png │ │ ├── bilibili_logo_red.png │ │ ├── douyin.png │ │ ├── github-mark-white.png │ │ ├── github-mark.png │ │ ├── logo.png │ │ ├── qq.png │ │ ├── storybook.svg │ │ ├── typescript.svg │ │ └── vue.png │ ├── scss │ │ └── theme.scss │ ├── svg │ │ └── phone-hangup.svg │ └── video │ │ └── tray_guide.webm ├── common │ ├── Constants.ts │ └── dayjs-extend.ts ├── components │ ├── DatePickerDialog.vue │ ├── FontSelector.vue │ ├── LunarDatePicker.vue │ ├── SolarDatePicker.vue │ ├── TimePicker.vue │ └── TimePickerDialog.vue ├── composition │ ├── useAppConfig.ts │ ├── useAppRuntimeInfo.ts │ └── useWidgetPackage.ts ├── countdown │ ├── CountdownList.vue │ └── Event.ts ├── i18n │ ├── default │ │ ├── en.json │ │ └── zh.json │ ├── i18n.ts │ ├── settings │ │ ├── en.json │ │ └── zh.json │ └── tray │ │ ├── en.json │ │ └── zh.json ├── index.css ├── main.ts ├── model │ ├── AppVersion.ts │ └── FeatureWall.ts ├── router │ └── index.ts ├── shims-vue.d.ts ├── util │ ├── LunarUtils.ts │ └── TimeUtils.ts ├── utils │ ├── TimeUtils.ts │ ├── VersionUtils.ts │ └── WidgetUtil.ts ├── views │ ├── Loading.vue │ ├── add │ │ ├── AddWidgetView.vue │ │ ├── SearchItem.vue │ │ ├── WidgetContainer.vue │ │ ├── WidgetTags.vue │ │ └── feature │ │ │ ├── FeatureWallList.vue │ │ │ └── FeatureWallListItem.vue │ ├── desktop │ │ ├── Grid.vue │ │ ├── GridSystem.ts │ │ ├── GridSystemDrawer.ts │ │ ├── Loading.vue │ │ ├── TrayGuide.vue │ │ └── WidgetFailed.vue │ ├── manager │ │ ├── DeployedWidgetCard.vue │ │ ├── DeployedWidgetList.vue │ │ └── ManagerView.vue │ ├── overlap │ │ ├── OverlapGuide.vue │ │ └── OverlapWrapper.vue │ ├── settings │ │ ├── AiSettingPanel.vue │ │ ├── AppRuntimeView.vue │ │ ├── ProxySettingPanel.vue │ │ ├── SettingSection.vue │ │ ├── SettingView.vue │ │ └── theme │ │ │ ├── ThemeSettingPanel.vue │ │ │ ├── ThemeTag.ts │ │ │ └── ThemeTags.vue │ ├── tray │ │ ├── SocialLinks.vue │ │ └── TrayMenuView.vue │ └── update │ │ └── CheckUpdateView.vue ├── vite-env.d.ts └── widgets │ ├── birthday-list │ ├── BirthdayList.widget.ts │ ├── BirthdayListConfigView.vue │ ├── BirthdayListWidget.vue │ ├── BirthdayListWidgetRoutes.ts │ ├── BirthdayListWidgetView.vue │ ├── images │ │ └── balloon.png │ └── model │ │ └── BirthdayListData.ts │ ├── countdown │ ├── Countdown.widget.ts │ ├── CountdownConfigView.vue │ ├── CountdownWidget.vue │ ├── CountdownWidgetRoutes.ts │ ├── CountdownWidgetView.vue │ └── model │ │ └── CountdownModel.ts │ ├── countdown2 │ ├── Countdown2.widget.ts │ ├── Countdown2ConfigView.vue │ ├── Countdown2Widget.vue │ ├── Countdown2WidgetRoutes.ts │ └── Countdown2WidgetView.vue │ ├── dynamic-island │ ├── DynamicIsland.widget.ts │ ├── DynamicIslandWidget.vue │ ├── DynamicIslandWidgetRoutes.ts │ ├── DynamicIslandWidgetView.vue │ ├── components │ │ ├── AdvanceCountdownNotification.vue │ │ ├── CountingNotification.vue │ │ ├── CustomUrlNotification.vue │ │ ├── MessageNotification.vue │ │ ├── PhoneCallNotification.vue │ │ ├── ReminderNotification.vue │ │ └── VoiceBar.vue │ ├── model │ │ ├── Demo.ts │ │ └── NotificationState.ts │ └── scss │ │ └── notification.scss │ ├── key-stroke │ ├── KeyStroke.widget.ts │ ├── KeyStrokeWidget.vue │ ├── KeyStrokeWidgetRoutes.ts │ └── KeyStrokeWidgetView.vue │ ├── labor-progress │ ├── LaborProgress.widget.ts │ ├── LaborProgressConfigView.vue │ ├── LaborProgressRoutes.ts │ ├── LaborProgressWidget.vue │ ├── LaborProgressWidgetView.vue │ ├── images │ │ ├── face_holding_back_tears_3d.png │ │ ├── face_with_rolling_eyes_3d.png │ │ ├── face_with_spiral_eyes_3d.png │ │ ├── face_with_steam_from_nose_3d.png │ │ ├── knocked-out_face_3d.png │ │ ├── partying_face_3d.png │ │ ├── sleeping_face_3d.png │ │ ├── sleepy_face_3d.png │ │ ├── smiling_face_with_sunglasses_3d.png │ │ ├── star-struck_3d.png │ │ └── yawning_face_3d.png │ └── model │ │ ├── EmojiTimeline.ts │ │ └── LaborProgressData.ts │ ├── phone-reminder │ ├── PhoneReminder.widget.ts │ ├── PhoneReminderConfigView.vue │ ├── PhoneReminderWidgetRoutes.ts │ ├── PhoneReminderWidgetView.vue │ └── model │ │ └── PhoneReminder.ts │ ├── photo │ ├── Photo.widget.ts │ ├── PhotoConfigView.vue │ ├── PhotoWidgetRoutes.ts │ ├── PhotoWidgetView.vue │ ├── assets │ │ ├── photo1.jpg │ │ ├── photo2.jpg │ │ └── photo3.jpg │ └── model │ │ └── PhotoData.ts │ ├── sit-reminder │ ├── BreakView.vue │ ├── SitReminder.widget.ts │ ├── SitReminderConfigView.vue │ ├── SitReminderWidget.vue │ ├── SitReminderWidgetRoutes.ts │ ├── TextSwitcher.vue │ ├── composition │ │ └── use-sit-reminder.ts │ └── model │ │ └── SitReminder.ts │ ├── time-progress │ ├── TimeProgress.widget.ts │ ├── TimeProgressConfig.vue │ ├── TimeProgressRoutes.ts │ ├── TimeProgressWidgetView.vue │ └── images │ │ └── time_progress_decorate.svg │ ├── todo-list │ ├── TodoList.widget.ts │ ├── TodoListConfigView.vue │ ├── TodoListWidgetRoutes.ts │ ├── TodoListWidgetView.vue │ ├── WidgetBackground.vue │ ├── components │ │ ├── EditBox.vue │ │ ├── FinishedTodoList.vue │ │ ├── TodoItem.vue │ │ └── TodoList.vue │ └── model │ │ ├── TodoListData.ts │ │ └── useTodoStore.ts │ ├── water-reminder │ ├── WaterReminder.widget.ts │ ├── WaterReminderComponent.vue │ ├── WaterReminderConfigView.vue │ ├── WaterReminderWidgetRoutes.ts │ ├── WaterReminderWidgetView.vue │ └── model │ │ ├── WaterReminderModel.ts │ │ └── WaveBall.ts │ ├── wave-progress │ ├── WaveProgress.widget.ts │ ├── WaveProgressConfigView.vue │ ├── WaveProgressRoute.ts │ ├── WaveProgressWidget.vue │ ├── WaveProgressWidgetView.vue │ └── model │ │ └── WaveProgressData.ts │ └── widget-router.ts ├── test └── dayjs.test.ts ├── tsconfig.json ├── tsconfig.node.json ├── uno.config.ts ├── vite.config.ts └── widget.package.ts /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | not ie 11 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules 3 | patches/ 4 | types/ 5 | cache/ 6 | !packages/.vitepress 7 | !/.eslintrc.js 8 | !/rollup.config.js 9 | !.test 10 | .temp 11 | -------------------------------------------------------------------------------- /.github/workflows/github-page.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs 3 | 4 | name: Deploy CI 5 | permissions: 6 | id-token: write 7 | pages: write 8 | 9 | on: 10 | push: 11 | branches: [ "master" ] 12 | pull_request: 13 | branches: [ "master" ] 14 | 15 | jobs: 16 | build: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v4 21 | - name: Use Node.js 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: '18.x' 25 | - name: Setup pnpm 26 | uses: pnpm/action-setup@v4 27 | with: 28 | version: 8 29 | - name: Build static files 30 | id: build 31 | run: | 32 | pnpm install 33 | pnpm run build 34 | - name: Upload static files as artifact 35 | id: deployment 36 | uses: actions/upload-pages-artifact@v3 37 | with: 38 | path: dist/ 39 | 40 | deploy: 41 | environment: 42 | name: github-pages 43 | url: ${{ steps.deployment.outputs.page_url }} 44 | runs-on: ubuntu-latest 45 | needs: build 46 | steps: 47 | - name: Deploy to GitHub Pages 48 | id: deployment 49 | uses: actions/deploy-pages@v4 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | storybook-static 5 | 6 | 7 | # local env files 8 | .env.local 9 | .env.*.local 10 | 11 | # Log files 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | pnpm-debug.log* 16 | 17 | # Editor directories and files 18 | .idea 19 | .vscode 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | .eslintcache 26 | #Electron-builder output 27 | /dist_electron 28 | -------------------------------------------------------------------------------- /auto-imports.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by 'unplugin-auto-import' 2 | export {} 3 | declare global { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /components.d.ts: -------------------------------------------------------------------------------- 1 | // generated by unplugin-vue-components 2 | // We suggest you to commit this file into source control 3 | // Read more: https://github.com/vuejs/core/pull/3399 4 | import '@vue/runtime-core' 5 | 6 | export {} 7 | 8 | declare module '@vue/runtime-core' { 9 | export interface GlobalComponents { 10 | DatePickerDialog: typeof import('./src/components/DatePickerDialog.vue')['default'] 11 | ElAlert: typeof import('element-plus/es')['ElAlert'] 12 | ElAvatar: typeof import('element-plus/es')['ElAvatar'] 13 | ElButton: typeof import('element-plus/es')['ElButton'] 14 | ElCard: typeof import('element-plus/es')['ElCard'] 15 | ElCarousel: typeof import('element-plus/es')['ElCarousel'] 16 | ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem'] 17 | ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] 18 | ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] 19 | ElCol: typeof import('element-plus/es')['ElCol'] 20 | ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] 21 | ElDialog: typeof import('element-plus/es')['ElDialog'] 22 | ElDivider: typeof import('element-plus/es')['ElDivider'] 23 | ElForm: typeof import('element-plus/es')['ElForm'] 24 | ElFormItem: typeof import('element-plus/es')['ElFormItem'] 25 | ElImage: typeof import('element-plus/es')['ElImage'] 26 | ElImageViewer: typeof import('element-plus/es')['ElImageViewer'] 27 | ElInput: typeof import('element-plus/es')['ElInput'] 28 | ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] 29 | ElOption: typeof import('element-plus/es')['ElOption'] 30 | ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm'] 31 | ElPopover: typeof import('element-plus/es')['ElPopover'] 32 | ElRadio: typeof import('element-plus/es')['ElRadio'] 33 | ElRadioButton: typeof import('element-plus/es')['ElRadioButton'] 34 | ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] 35 | ElRow: typeof import('element-plus/es')['ElRow'] 36 | ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] 37 | ElSelect: typeof import('element-plus/es')['ElSelect'] 38 | ElSwitch: typeof import('element-plus/es')['ElSwitch'] 39 | ElTable: typeof import('element-plus/es')['ElTable'] 40 | ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] 41 | ElTabPane: typeof import('element-plus/es')['ElTabPane'] 42 | ElTabs: typeof import('element-plus/es')['ElTabs'] 43 | ElTag: typeof import('element-plus/es')['ElTag'] 44 | ElTimePicker: typeof import('element-plus/es')['ElTimePicker'] 45 | ElTooltip: typeof import('element-plus/es')['ElTooltip'] 46 | FontSelector: typeof import('./src/components/FontSelector.vue')['default'] 47 | LunarDatePicker: typeof import('./src/components/LunarDatePicker.vue')['default'] 48 | RouterLink: typeof import('vue-router')['RouterLink'] 49 | RouterView: typeof import('vue-router')['RouterView'] 50 | SolarDatePicker: typeof import('./src/components/SolarDatePicker.vue')['default'] 51 | TimePicker: typeof import('./src/components/TimePicker.vue')['default'] 52 | TimePickerDialog: typeof import('./src/components/TimePickerDialog.vue')['default'] 53 | } 54 | export interface ComponentCustomProperties { 55 | vLoading: typeof import('element-plus/es')['ElLoadingDirective'] 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import antfu from '@antfu/eslint-config' 2 | 3 | export default antfu({ 4 | ignores: ['**/*.md', '**/*.md/*.*', 'dist/', 'public/', '**/dist/**/', 'node_modules', '**/node_modules/**', 'node_modules/', '**/node_modules/**/', 'patches/', '**/patches/**/', 'types/', '**/types/**/', 'cache/', '**/cache/**/', '!packages/.vitepress', '!packages/.vitepress/**', '!.eslintrc.js', '!.eslintrc.js/**', '!rollup.config.js', '!rollup.config.js/**', '!.test', '!**/.test/**', '.temp', '**/.temp/**'], 5 | }, { 6 | rules: { 7 | 'vue/no-deprecated-functional-template': 'off', 8 | 'vue/one-component-per-file': 'off', 9 | 'vue/no-template-shadow': 'off', 10 | 'vue/require-prop-types': 'off', 11 | 'vue/dot-location': 'off', 12 | 'spaced-comment': ['error', 'always', { exceptions: ['#__PURE__'] }], 13 | 'no-restricted-imports': [ 14 | 'error', 15 | { 16 | patterns: ['../**/core', '../**/vue3'], 17 | }, 18 | ], 19 | 'vue/eqeqeq': 'off', 20 | 'vue/space-unary-ops': 'off', 21 | 'vue/comma-dangle': ['error', 'only-multiline'], 22 | 'node/no-callback-literal': 'off', 23 | 'import/namespace': 'off', 24 | 'eqeqeq': 'off', 25 | 'import/default': 'off', 26 | 'import/no-named-as-default': 'off', 27 | 'import/no-named-as-default-member': 'off', 28 | 'curly': ['error', 'multi-line'], 29 | 'max-statements-per-line': ['error', { 30 | max: 1, 31 | }], 32 | }, 33 | }, { 34 | files: ['demo.vue', 'demo.client.vue', 'scripts/*.ts', '**/*.test.ts'], 35 | rules: { 36 | 'no-alert': 'off', 37 | 'no-console': 'off', 38 | 'no-undef': 'off', 39 | 'no-unused-vars': 'off', 40 | 'no-restricted-imports': 'off', 41 | '@typescript-eslint/no-unused-vars': 'off', 42 | '@typescript-eslint/no-redeclare': 'off', 43 | 'unused-imports/no-unused-vars': 'off', 44 | }, 45 | }) 46 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Widget 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@widget-js/widgets", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "private": true, 6 | "author": "Widget JS", 7 | "license": "MIT", 8 | "scripts": { 9 | "serve": "vite", 10 | "build": "vite build", 11 | "preview": "vite preview", 12 | "remote": "widget dependencies -t remote", 13 | "local": "widget dependencies -t local", 14 | "lint": "eslint --cache .", 15 | "lint:fix": "eslint --cache . --fix" 16 | }, 17 | "dependencies": { 18 | "@icon-park/vue-next": "^1.4.2", 19 | "@lobehub/icons": "^1.76.0", 20 | "@vueuse/core": "^9.4.0", 21 | "@vueuse/integrations": "^10.5.0", 22 | "@vueuse/motion": "2.0.0-beta.12", 23 | "@vueuse/router": "^9.9.0", 24 | "@widget-js/core": "^24.1.1-beta.34", 25 | "@widget-js/vue3": "^24.1.1-beta.33", 26 | "@widget-js/web-api": "24.1.1-beta.42", 27 | "animate.css": "^4.1.1", 28 | "axios": "^1.6.0", 29 | "color": "^4.2.3", 30 | "consola": "^3.2.3", 31 | "core-js": "^3.26.1", 32 | "dayjs": "^1.11.6", 33 | "driver.js": "^0.9.8", 34 | "element-plus": "2.9.8", 35 | "localforage": "^1.10.0", 36 | "lodash-es": "^4.17.21", 37 | "lunar-typescript": "^1.7.0", 38 | "lyric-resolver": "^0.1.6", 39 | "nanoid": "^4.0.2", 40 | "pinia": "^2.1.6", 41 | "qs": "^6.11.2", 42 | "semver": "^7.6.0", 43 | "vue": "^3.5.13", 44 | "vue-demi": "^0.14.5", 45 | "vue-i18n": "10.0.5", 46 | "vue-router": "^4.2.4", 47 | "vue-scroll-picker": "^1.1.3" 48 | }, 49 | "devDependencies": { 50 | "@antfu/eslint-config": "^2.6.1", 51 | "@antfu/ni": "^0.21.4", 52 | "@types/color": "^3.0.3", 53 | "@types/lodash-es": "^4.17.12", 54 | "@typescript-eslint/eslint-plugin": "^6.16.0", 55 | "@typescript-eslint/parser": "^6.16.0", 56 | "@vitejs/plugin-vue": "^4.0.0", 57 | "@vue/cli-plugin-router": "~5.0.0", 58 | "@vue/cli-plugin-typescript": "~5.0.0", 59 | "@vue/cli-service": "~5.0.0", 60 | "@vue/compiler-sfc": "^3.2.45", 61 | "@widget-js/vite-plugin-widget": "^24.1.1-beta.30", 62 | "autoprefixer": "^10.4.13", 63 | "eslint": "8.48.0", 64 | "lint-staged": "^13.0.3", 65 | "postcss": "^8.4.21", 66 | "sass": "^1.56.0", 67 | "simple-git-hooks": "^2.9.0", 68 | "style-loader": "^3.3.1", 69 | "typescript": "^5.2.2", 70 | "unocss": "^0.51.13", 71 | "unplugin-auto-import": "^0.11.4", 72 | "unplugin-vue-components": "^0.22.9", 73 | "vite": "^5.0.5", 74 | "vite-plugin-checker": "^0.6.1", 75 | "vitest": "^0.34.6" 76 | }, 77 | "simple-git-hooks": { 78 | "pre-commit": "npx lint-staged" 79 | }, 80 | "lint-staged": { 81 | "*.{js,ts,tsx,vue,md}": [ 82 | "eslint --cache --fix" 83 | ] 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /public/audio/ding.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/audio/ding.mp3 -------------------------------------------------------------------------------- /public/audio/hangup.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/audio/hangup.m4a -------------------------------------------------------------------------------- /public/audio/ringtone.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/audio/ringtone.m4a -------------------------------------------------------------------------------- /public/audio/voice/elvis.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/audio/voice/elvis.mp3 -------------------------------------------------------------------------------- /public/audio/voice/jackie_chan.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/audio/voice/jackie_chan.wav -------------------------------------------------------------------------------- /public/audio/voice/mrs_pan.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/audio/voice/mrs_pan.m4a -------------------------------------------------------------------------------- /public/audio/voice/squidward.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/audio/voice/squidward.m4a -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/favicon.ico -------------------------------------------------------------------------------- /public/firework/script.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/firework/script.js -------------------------------------------------------------------------------- /public/font/SairaExtraCondensed-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/font/SairaExtraCondensed-Regular.ttf -------------------------------------------------------------------------------- /public/font/SairaExtraCondensed-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/font/SairaExtraCondensed-Regular.woff -------------------------------------------------------------------------------- /public/font/SairaExtraCondensed-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/font/SairaExtraCondensed-Regular.woff2 -------------------------------------------------------------------------------- /public/images/avatar/elvis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/avatar/elvis.png -------------------------------------------------------------------------------- /public/images/avatar/international_friend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/avatar/international_friend.png -------------------------------------------------------------------------------- /public/images/avatar/jackie_chan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/avatar/jackie_chan.jpg -------------------------------------------------------------------------------- /public/images/avatar/mrs_pan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/avatar/mrs_pan.jpg -------------------------------------------------------------------------------- /public/images/preview_birthday_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_birthday_list.png -------------------------------------------------------------------------------- /public/images/preview_clipboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_clipboard.png -------------------------------------------------------------------------------- /public/images/preview_countdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_countdown.png -------------------------------------------------------------------------------- /public/images/preview_countdown2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_countdown2.png -------------------------------------------------------------------------------- /public/images/preview_keystroke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_keystroke.png -------------------------------------------------------------------------------- /public/images/preview_labor_progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_labor_progress.png -------------------------------------------------------------------------------- /public/images/preview_lyric_book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_lyric_book.png -------------------------------------------------------------------------------- /public/images/preview_phone_reminder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_phone_reminder.png -------------------------------------------------------------------------------- /public/images/preview_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_photo.png -------------------------------------------------------------------------------- /public/images/preview_sit_reminder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_sit_reminder.png -------------------------------------------------------------------------------- /public/images/preview_time_progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_time_progress.png -------------------------------------------------------------------------------- /public/images/preview_todo_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_todo_list.png -------------------------------------------------------------------------------- /public/images/preview_water_reminder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_water_reminder.png -------------------------------------------------------------------------------- /public/images/preview_wave_progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/preview_wave_progress.png -------------------------------------------------------------------------------- /public/images/zhangyuge.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/images/zhangyuge.jpg -------------------------------------------------------------------------------- /public/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/public/screenshot.jpg -------------------------------------------------------------------------------- /screenshot/dynamic_island.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/screenshot/dynamic_island.gif -------------------------------------------------------------------------------- /screenshot/labor_progress.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/screenshot/labor_progress.gif -------------------------------------------------------------------------------- /screenshot/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/screenshot/logo.png -------------------------------------------------------------------------------- /screenshot/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/screenshot/photo.png -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 18 | 19 | 25 | -------------------------------------------------------------------------------- /src/api/FeatureWallApi.ts: -------------------------------------------------------------------------------- 1 | import type { FeatureWall } from '../model/FeatureWall' 2 | import { widgetServerApi } from '@/api/axios' 3 | 4 | export class FeatureWallApi { 5 | // 获取所有 FeatureWall 6 | static findAll(): Promise { 7 | return widgetServerApi.get('/feature/wall') 8 | } 9 | 10 | // 点赞 FeatureWall 11 | static like(id: number): Promise { 12 | return widgetServerApi.post(`/feature/wall/${id}/like`) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/api/WebWidgetApi.ts: -------------------------------------------------------------------------------- 1 | import type { Pagination, WebWidget, WidgetSearchOptions } from '@widget-js/web-api' 2 | import { widgetServerApi } from '@/api/axios' 3 | 4 | export class WebWidgetApi { 5 | static search(options: WidgetSearchOptions): Promise> { 6 | return widgetServerApi.get('/widget', { params: options }) 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/api/axios.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | AxiosError, 3 | AxiosInstance, 4 | AxiosRequestHeaders, 5 | AxiosResponse, 6 | InternalAxiosRequestConfig, 7 | } from 'axios' 8 | import axios from 'axios' 9 | 10 | import qs from 'qs' 11 | 12 | import { LogApi } from '@widget-js/core' 13 | 14 | axios.defaults.baseURL = 'https://widgetjs.cn/api/v1' 15 | const widgetServerApi: AxiosInstance = axios.create({ 16 | timeout: 60000, 17 | }) 18 | 19 | // request拦截器 20 | widgetServerApi.interceptors.request.use( 21 | (config: InternalAxiosRequestConfig) => { 22 | if ( 23 | config.method === 'post' 24 | && (config.headers as AxiosRequestHeaders)['Content-Type'] === 'application/x-www-form-urlencoded' 25 | ) { 26 | config.data = qs.stringify(config.data) 27 | } 28 | if (config.method === 'get' && config.params) { 29 | let url = config.url as string 30 | url += '?' 31 | const keys = Object.keys(config.params) 32 | for (const key of keys) { 33 | if (config.params[key] !== void 0 && config.params[key] !== null) { 34 | url += `${key}=${encodeURIComponent(config.params[key])}&` 35 | } 36 | } 37 | url = url.substring(0, url.length - 1) 38 | config.params = {} 39 | config.url = url 40 | } 41 | return config 42 | }, 43 | (error: AxiosError) => { 44 | LogApi.error('axios', { 45 | code: error.code, 46 | message: error.message, 47 | name: error.name, 48 | }) 49 | return Promise.reject(error) 50 | }, 51 | ) 52 | 53 | // response 拦截器 54 | widgetServerApi.interceptors.response.use( 55 | (response: AxiosResponse) => { 56 | if (response.config.responseType === 'blob') { 57 | // 如果是文件流,直接过 58 | return response 59 | } 60 | else if (response.data.code === 200) { 61 | return response.data.data 62 | } 63 | else { 64 | return Promise.reject(response.data) 65 | } 66 | }, 67 | (error: AxiosError) => { 68 | LogApi.error('axios', { 69 | code: error.code, 70 | message: error.message, 71 | name: error.name, 72 | }) 73 | return Promise.reject(error) 74 | }, 75 | ) 76 | 77 | export { widgetServerApi } 78 | -------------------------------------------------------------------------------- /src/assets/cancel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/css/common.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | body, *, view { 5 | box-sizing: border-box; 6 | user-select: none; 7 | -webkit-user-drag: none; 8 | } 9 | 10 | body { 11 | margin: 0; 12 | } 13 | 14 | button { 15 | margin: 0; 16 | padding: 0; 17 | border: 1px solid transparent; 18 | outline: none; 19 | background-color: transparent; 20 | } 21 | 22 | button:active { 23 | opacity: 0.6; 24 | } 25 | 26 | .flex-col { 27 | display: flex; 28 | flex-direction: column; 29 | } 30 | 31 | .flex-row { 32 | display: flex; 33 | flex-direction: row; 34 | } 35 | 36 | .justify-start { 37 | display: flex; 38 | justify-content: flex-start; 39 | } 40 | 41 | .justify-center { 42 | display: flex; 43 | justify-content: center; 44 | } 45 | 46 | .justify-end { 47 | display: flex; 48 | justify-content: flex-end; 49 | } 50 | 51 | .justify-evenly { 52 | display: flex; 53 | justify-content: space-evenly; 54 | } 55 | 56 | .justify-around { 57 | display: flex; 58 | justify-content: space-around; 59 | } 60 | 61 | .justify-between { 62 | display: flex; 63 | justify-content: space-between; 64 | } 65 | 66 | .align-start { 67 | display: flex; 68 | align-items: flex-start; 69 | } 70 | 71 | .align-center { 72 | display: flex; 73 | align-items: center; 74 | } 75 | 76 | .align-end { 77 | display: flex; 78 | align-items: flex-end; 79 | } 80 | -------------------------------------------------------------------------------- /src/assets/images/bilibili_logo_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/src/assets/images/bilibili_logo_blue.png -------------------------------------------------------------------------------- /src/assets/images/bilibili_logo_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/src/assets/images/bilibili_logo_red.png -------------------------------------------------------------------------------- /src/assets/images/douyin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/src/assets/images/douyin.png -------------------------------------------------------------------------------- /src/assets/images/github-mark-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/src/assets/images/github-mark-white.png -------------------------------------------------------------------------------- /src/assets/images/github-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/src/assets/images/github-mark.png -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/src/assets/images/qq.png -------------------------------------------------------------------------------- /src/assets/images/storybook.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/typescript.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/assets/images/vue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/src/assets/images/vue.png -------------------------------------------------------------------------------- /src/assets/scss/theme.scss: -------------------------------------------------------------------------------- 1 | @use "sass:map"; 2 | @import "element-plus/theme-chalk/src/common/var.scss"; 3 | 4 | $text-color-primary: map.get($text-color, "primary"); 5 | $border-radius-base: map.get($border-radius, "base"); 6 | $fill-color-default: map.get($fill-color, ''); 7 | $box-shadow-default: map.get($box-shadow, ''); 8 | 9 | $weight-regular: 400; 10 | $weight-bold: 700; 11 | 12 | @mixin electron-dialog{ 13 | background-color: $fill-color-default; 14 | border-radius: $border-radius-base; 15 | box-shadow: $box-shadow-default; 16 | margin: 32px; 17 | border-width: 1px; 18 | border-color: rgba(0, 0, 0, 0.11); 19 | border-style: solid; 20 | } 21 | 22 | @mixin title-medium { 23 | font-weight: $weight-regular; 24 | font-size: 16px; 25 | color: $text-color-primary; 26 | } 27 | 28 | @mixin title-medium-bold { 29 | font-weight: $weight-bold; 30 | font-size: 16px; 31 | color: $text-color-primary; 32 | } 33 | -------------------------------------------------------------------------------- /src/assets/svg/phone-hangup.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /src/assets/video/tray_guide.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widget-js/widgets/396da26cf98b836b00cb780f646f810a9803c172/src/assets/video/tray_guide.webm -------------------------------------------------------------------------------- /src/common/Constants.ts: -------------------------------------------------------------------------------- 1 | export default class Constants { 2 | static readonly GUIDE_KEY_OVERLAP_MENU = 'Aijee1zeiY7meeghiewiebahfei0ic1' 3 | } 4 | -------------------------------------------------------------------------------- /src/common/dayjs-extend.ts: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs' 2 | import isoWeek from 'dayjs/plugin/isoWeek' 3 | import objectSupport from 'dayjs/plugin/objectSupport' 4 | import isBetween from 'dayjs/plugin/isBetween' 5 | import weekday from 'dayjs/plugin/weekday' 6 | import duration from 'dayjs/plugin/duration' 7 | 8 | dayjs.extend(duration) 9 | dayjs.extend(weekday) 10 | dayjs.extend(objectSupport) 11 | dayjs.extend(isBetween) 12 | dayjs.extend(isoWeek) 13 | -------------------------------------------------------------------------------- /src/components/DatePickerDialog.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 68 | 69 | 80 | -------------------------------------------------------------------------------- /src/components/FontSelector.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 49 | 50 | 53 | -------------------------------------------------------------------------------- /src/components/LunarDatePicker.vue: -------------------------------------------------------------------------------- 1 | 104 | 105 | 112 | 113 | 123 | -------------------------------------------------------------------------------- /src/components/SolarDatePicker.vue: -------------------------------------------------------------------------------- 1 | 63 | 64 | 71 | 72 | 82 | -------------------------------------------------------------------------------- /src/components/TimePicker.vue: -------------------------------------------------------------------------------- 1 | 70 | 71 | 77 | 78 | 88 | -------------------------------------------------------------------------------- /src/components/TimePickerDialog.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 50 | 51 | 62 | -------------------------------------------------------------------------------- /src/composition/useAppConfig.ts: -------------------------------------------------------------------------------- 1 | import type { LanguageCode } from '@widget-js/core' 2 | import { AppApi } from '@widget-js/core' 3 | import { onMounted, ref, watch } from 'vue' 4 | 5 | const debugMode = ref(false) 6 | export function useDebugConfig(onLoad?: (debug: boolean) => void) { 7 | onMounted(async () => { 8 | debugMode.value = await AppApi.getDevMode() 9 | onLoad?.(debugMode.value) 10 | watch(debugMode, async (newValue) => { 11 | await AppApi.setDevMode(newValue) 12 | }) 13 | }) 14 | return debugMode 15 | } 16 | 17 | export function useCellSizeConfig() { 18 | const gridSize = ref(80) 19 | onMounted(async () => { 20 | gridSize.value = await AppApi.getGridCellSize() 21 | watch(gridSize, async (newValue) => { 22 | await AppApi.setGridCellSize(newValue) 23 | }) 24 | }) 25 | 26 | return gridSize 27 | } 28 | 29 | export function useLanguageConfig() { 30 | const languageCode = ref(navigator.language) 31 | let inited = false 32 | AppApi.getLanguageCode().then((result) => { 33 | languageCode.value = result 34 | inited = true 35 | }) 36 | 37 | watch(languageCode, async (newValue) => { 38 | if (inited) { 39 | await AppApi.setLanguageCode(newValue as LanguageCode) 40 | } 41 | }) 42 | return languageCode 43 | } 44 | -------------------------------------------------------------------------------- /src/composition/useAppRuntimeInfo.ts: -------------------------------------------------------------------------------- 1 | import type { AppRuntimeInfo } from '@widget-js/core' 2 | import { AppApi } from '@widget-js/core' 3 | import { computed, ref } from 'vue' 4 | 5 | export type SimpleAppRuntimeInfo = Omit 6 | export function useAppRuntimeInfo() { 7 | const info = ref() 8 | 9 | AppApi.getRuntimeInfo().then((data) => { 10 | // sort keys 11 | const res = Object.keys(data).sort().reduce((obj, key) => { 12 | obj[key] = data[key] 13 | return obj 14 | }, {}) 15 | info.value = res as AppRuntimeInfo 16 | }) 17 | 18 | const simpleInfo = computed(() => { 19 | if (info.value) { 20 | const simple: SimpleAppRuntimeInfo = { 21 | app: info.value.app, 22 | cpuModel: info.value.cpuModel, 23 | arch: info.value.arch, 24 | electron: info.value.electron, 25 | release: info.value.release, 26 | isWindowsStore: info.value.isWindowsStore, 27 | totalMem: info.value.totalMem, 28 | systemName: info.value.systemName, 29 | } 30 | return simple 31 | } 32 | return undefined 33 | }) 34 | 35 | return { info, simpleInfo } 36 | } 37 | -------------------------------------------------------------------------------- /src/composition/useWidgetPackage.ts: -------------------------------------------------------------------------------- 1 | import type { RemotePackageUrlInfo } from '@widget-js/core' 2 | import { NotificationApi, WidgetPackageApi } from '@widget-js/core' 3 | import semver from 'semver' 4 | import type { ComputedRef, Ref } from 'vue' 5 | import { computed, reactive, ref, toRaw } from 'vue' 6 | import consola from 'consola' 7 | 8 | export interface UseWidgetPackageReturn { 9 | upgrading: ComputedRef 10 | upgradable: Ref 11 | checkUpgrade: () => Promise 12 | upgradePackage: () => Promise 13 | } 14 | 15 | const upgradablePackages = reactive([]) 16 | const upgradingPackages = reactive([]) 17 | const instanceCache = new Map() 18 | 19 | export function useWidgetPackage(packageName: string, remoteVersion: string, remoteUrlInfo?: RemotePackageUrlInfo): UseWidgetPackageReturn { 20 | if (instanceCache.has(packageName)) { 21 | return instanceCache.get(packageName)! 22 | } 23 | const checking = ref(false) 24 | 25 | const upgrading = computed(() => { 26 | return upgradingPackages.includes(packageName) 27 | }) 28 | 29 | const upgradable = ref(false) 30 | 31 | const checkUpgrade = async (): Promise => { 32 | if (checking.value) { 33 | return false 34 | } 35 | checking.value = true 36 | try { 37 | const widgetPackage = await WidgetPackageApi.getPackage(packageName) 38 | if (widgetPackage) { 39 | if (widgetPackage.name == 'widget.js.fun') { 40 | consola.log(remoteVersion) 41 | } 42 | upgradable.value = semver.gt(remoteVersion, widgetPackage.version ?? '1.0.0') 43 | if (upgradable.value && !upgradablePackages.includes(packageName)) { 44 | upgradablePackages.push(packageName) 45 | } 46 | return upgradable.value 47 | } 48 | upgradablePackages.splice(upgradablePackages.indexOf(packageName), 1) 49 | } 50 | catch (e) { 51 | consola.error(e) 52 | } 53 | checking.value = false 54 | return false 55 | } 56 | 57 | const upgradePackage = async () => { 58 | upgradingPackages.push(packageName) 59 | try { 60 | if (!remoteUrlInfo) { 61 | NotificationApi.error('未配置组件包信息') 62 | return 63 | } 64 | await WidgetPackageApi.upgrade(packageName, toRaw(remoteUrlInfo)) 65 | upgradingPackages.splice(upgradingPackages.indexOf(packageName), 1) 66 | upgradablePackages.splice(upgradablePackages.indexOf(packageName), 1) 67 | NotificationApi.success('组件包升级成功') 68 | upgradable.value = false 69 | } 70 | catch (e) { 71 | console.error(e) 72 | } 73 | } 74 | const instance: UseWidgetPackageReturn = { upgrading, upgradable, checkUpgrade, upgradePackage } 75 | instanceCache.set(packageName, instance) 76 | return instance 77 | } 78 | -------------------------------------------------------------------------------- /src/countdown/CountdownList.vue: -------------------------------------------------------------------------------- 1 | 3 | 4 |