Skip to content

Commit dd737fd

Browse files
committed
Refactor CSS styles, add DropMask component, and enhance widget search functionality
1 parent 92f0ccb commit dd737fd

File tree

12 files changed

+204
-171
lines changed

12 files changed

+204
-171
lines changed

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ pnpm serve
7575

7676
## 监控组件包
7777

78-
| 监控组件包 |
79-
|:--------------------------------------------------------------------------------------------------------------:|
80-
| ![监控面板](https://github.com/rtugeek/monitor/blob/master/public/image/preview_base_panel.png?raw=true) <br/>监控面板 |
78+
| 监控组件包 |
79+
|:------------------------------------------------------------------------------------------------------------------:|
80+
| ![监控面板](https://github.com/rtugeek/monitor/blob/master/public/image/preview_base_panel.png?raw=true) <br/>监控面板 |
81+
| ![监控面板](https://github.com/rtugeek/monitor/blob/master/public/image/preview_energy_label.png?raw=true) <br/>打工能耗标签 |
82+
| ![监控面板](https://github.com/rtugeek/monitor/blob/master/public/image/preview_server.png?raw=true) <br/>服务器监控面板 |
8183

8284
## 默认组件包
8385

@@ -96,6 +98,12 @@ https://github.com/rtugeek/ai
9698

9799
![png](https://raw.githubusercontent.com/rtugeek/ai/master/screenshot.png)
98100

101+
## 文件夹
102+
103+
https://github.com/rtugeek/grid
104+
105+
![png](https://raw.githubusercontent.com/rtugeek/grid/refs/heads/master/public/preview_grid.png)
106+
99107
## iTime组件包
100108

101109
| iTime组件包 | https://github.com/rtugeek/itime-web |

package.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,22 @@
1717
"dependencies": {
1818
"@icon-park/vue-next": "^1.4.2",
1919
"@lobehub/icons": "^1.76.0",
20-
"@vueuse/core": "^9.4.0",
20+
"@vueuse/core": "^13.5.0",
2121
"@vueuse/integrations": "^10.5.0",
2222
"@vueuse/motion": "2.0.0-beta.12",
2323
"@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",
24+
"@vueuse/shared": "^13.5.0",
25+
"@widget-js/core": "workspace:*",
26+
"@widget-js/vue3": "workspace:*",
27+
"@widget-js/web-api": "24.1.1-beta.45",
2728
"animate.css": "^4.1.1",
2829
"axios": "^1.6.0",
2930
"color": "^4.2.3",
3031
"consola": "^3.2.3",
3132
"core-js": "^3.26.1",
3233
"dayjs": "^1.11.6",
3334
"driver.js": "^0.9.8",
34-
"element-plus": "2.9.8",
35+
"element-plus": "2.10.3",
3536
"localforage": "^1.10.0",
3637
"lodash-es": "^4.17.21",
3738
"lunar-typescript": "^1.7.0",
@@ -58,7 +59,7 @@
5859
"@vue/cli-plugin-typescript": "~5.0.0",
5960
"@vue/cli-service": "~5.0.0",
6061
"@vue/compiler-sfc": "^3.2.45",
61-
"@widget-js/vite-plugin-widget": "^24.1.1-beta.30",
62+
"@widget-js/vite-plugin-widget": "^24.1.1-beta.41",
6263
"autoprefixer": "^10.4.13",
6364
"eslint": "8.48.0",
6465
"lint-staged": "^13.0.3",

src/assets/css/common.css

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -23,57 +23,3 @@ button:active {
2323
opacity: 0.6;
2424
}
2525

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-
}

src/i18n/default/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"add": "Add",
2323
"disable": "Disable",
2424
"desktop": "Desktop",
25-
"overlap": "Overlap"
25+
"overlap": "Overlap",
26+
"tray": "Tray"
2627
},
2728
"tags": {
2829
"all": "All",

src/i18n/default/zh.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
"add": "添加",
3333
"upgrade": "升级",
3434
"enable": "启用",
35-
"disable": "禁用"
35+
"disable": "禁用",
36+
"tray": "托盘"
3637
},
3738
"manager": {
3839
"remove": "移除",

src/index.css

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,3 @@ button {
1717
outline: none;
1818
background-color: transparent;
1919
}
20-
21-
.flex {
22-
display: flex;
23-
}
24-
25-
.flex-1 {
26-
flex: 1 1 0%;
27-
}
28-
29-
.gap-1 {
30-
gap: 0.25rem;
31-
}
32-
33-
.gap-2 {
34-
gap: 0.5rem;
35-
}
36-
37-
.justify-center {
38-
justify-content: center;
39-
}
40-
41-
.items-center {
42-
align-items: center;
43-
}

src/views/add/AddWidgetView.vue

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,33 @@
11
<script lang="ts" setup>
2-
import { nextTick, onMounted, reactive, ref, watch } from 'vue'
2+
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
33
import { Code, Search } from '@icon-park/vue-next'
4-
import type { Widget } from '@widget-js/core'
5-
import { AppApi, BrowserWindowApi, ElectronUtils, WidgetApi, WidgetPackageApi } from '@widget-js/core'
4+
import type { Category, Widget } from '@widget-js/core'
5+
import { AppApi, BrowserWindowApi, ElectronUtils, NotificationApi, WidgetApi, WidgetPackageApi } from '@widget-js/core'
66
7-
import { useDebounceFn, useElementSize } from '@vueuse/core'
7+
import { useDebounceFn, useDropZone, useStorage, useWindowSize } from '@vueuse/core'
88
import type { WidgetSearchOptions } from '@widget-js/web-api'
99
import { WebWidget } from '@widget-js/web-api'
1010
import { useI18n } from 'vue-i18n'
11+
import { ElNotification } from 'element-plus'
12+
import consola from 'consola'
1113
import SearchItem from '@/views/add/SearchItem.vue'
1214
import { WebWidgetApi } from '@/api/WebWidgetApi'
1315
import WidgetTags from '@/views/add/WidgetTags.vue'
1416
import FeatureWallList from '@/views/add/feature/FeatureWallList.vue'
17+
import DropMask from '@/views/add/DropMask.vue'
1518
1619
const { t } = useI18n()
1720
const keyword = ref('')
1821
const selectedCategory = ref('')
1922
const windowRef = ref()
2023
const widgets = reactive<Widget[]>([])
2124
const loading = ref(true)
22-
const { height } = useElementSize(windowRef)
25+
const { height } = useWindowSize()
2326
onMounted(async () => {
2427
await nextTick()
2528
document.title = t('search.title')
2629
})
2730
28-
BrowserWindowApi.setup({ width: 750, height: 850, center: true })
29-
3031
async function search() {
3132
loading.value = true
3233
if (selectedCategory.value == 'debug') {
@@ -47,13 +48,26 @@ async function search() {
4748
}
4849
4950
const version = await AppApi.getVersion()
51+
const keywordStr = keyword.value.trim()
5052
const options: WidgetSearchOptions = {
5153
page: 1,
5254
pageSize: 50,
5355
category: selectedCategory.value,
54-
keyword: keyword.value.trim(),
56+
keyword: keywordStr,
5557
}
5658
options.appVersion = version
59+
let localWidgets = (await WidgetApi.getWidgets()).filter(it => !it.disabled)
60+
61+
if (selectedCategory.value) {
62+
localWidgets = localWidgets.filter(it => it.categories && it.categories.includes(selectedCategory.value as Category))
63+
}
64+
if (keywordStr) {
65+
localWidgets = localWidgets.filter((it) => {
66+
const title = JSON.stringify(it.title)
67+
const description = JSON.stringify(it.description)
68+
return title.includes(keywordStr) || description.includes(keywordStr)
69+
})
70+
}
5771
WebWidgetApi.search(options)
5872
.then((res) => {
5973
widgets.splice(0, widgets.length)
@@ -62,6 +76,16 @@ async function search() {
6276
.map(it => WebWidget.fromObject(it))
6377
.filter(it => it.name != 'cn.widgetjs.widgets.dynamic_island'),
6478
)
79+
for (const localWidget of localWidgets) {
80+
if (widgets.some(it => it.name == localWidget.name)) {
81+
continue
82+
}
83+
widgets.push(WebWidget.fromObject(localWidget))
84+
}
85+
})
86+
.catch(() => {
87+
widgets.splice(0, widgets.length)
88+
widgets.push(...localWidgets)
6589
})
6690
.finally(() => {
6791
loading.value = false
@@ -78,29 +102,58 @@ search()
78102
function goDevPage() {
79103
BrowserWindowApi.openUrl('https://widgetjs.cn/guide/', { external: true })
80104
}
105+
106+
const bodyRef = ref<HTMLDivElement>()
107+
const showKnowButton = useStorage('tip-drop-mask-button', true)
108+
109+
const { isOverDropZone } = useDropZone(bodyRef, {
110+
onDrop: async (files: File[] | null, _: DragEvent) => {
111+
if (files && files.length > 0) {
112+
const file = files[0]
113+
try {
114+
consola.info(`开始安装组件包: `, file)
115+
await WidgetPackageApi.install(file.path)
116+
await NotificationApi.success('安装成功')
117+
window.location.reload()
118+
}
119+
catch (e) {
120+
ElNotification({
121+
title: '安装失败',
122+
message: e.message,
123+
type: 'error',
124+
})
125+
}
126+
}
127+
},
128+
dataTypes: ['application/x-zip-compressed'],
129+
multiple: false,
130+
})
131+
132+
const isShowMask = computed(() => {
133+
return isOverDropZone.value || showKnowButton.value
134+
})
81135
</script>
82136

83137
<template>
84138
<div :class="{ browser: !ElectronUtils.hasElectronApi() }">
85-
<widget-base-dialog ref="windowRef" class="search-window" :body-padding="0" :title="t('search.title')">
139+
<WidgetBaseDialog ref="windowRef" class="search-window" :body-padding="0" :title="t('search.title')">
86140
<template #body>
87-
<div class="body">
88-
<el-row justify="center" class="px-4 pt-2">
141+
<div ref="bodyRef" class="dialog-body">
142+
<div class="px-4 pt-2 w-full flex gap-2">
89143
<el-input
90144
v-model="keyword"
91145
size="large"
92-
clearable
93-
class="round-border"
146+
class="round-border flex-1"
94147
:placeholder="t('search.placeholder')"
95148
@keydown.enter="search"
96149
>
97150
<template #prefix>
98151
<Search />
99152
</template>
100153
</el-input>
101-
</el-row>
154+
</div>
102155
<WidgetTags v-model="selectedCategory" class="px-4 pt-2" @change="search" />
103-
<el-scrollbar :height="height - 150">
156+
<el-scrollbar :height="height - 140">
104157
<el-row v-loading="loading" justify="start" class="px-4">
105158
<template v-if="selectedCategory == 'wish'">
106159
<FeatureWallList />
@@ -125,13 +178,14 @@ function goDevPage() {
125178
</template>
126179
</el-row>
127180
</el-scrollbar>
181+
<DropMask v-show="isShowMask" />
128182
</div>
129183
</template>
130-
</widget-base-dialog>
184+
</WidgetBaseDialog>
131185
</div>
132186
</template>
133187

134-
<style lang="scss">
188+
<style lang="scss" scoped>
135189
.browser{
136190
background-color: #e7e7e7;
137191
height: 100vh;
@@ -146,7 +200,9 @@ function goDevPage() {
146200
@import '@/assets/scss/theme.scss';
147201
148202
.dialog-wrapper {
149-
.body {
203+
.dialog-body {
204+
position: relative;
205+
height: calc(100vh - 42px);
150206
background-color: $fill-color-default;
151207
}
152208
}

src/views/add/DropMask.vue

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script setup lang="ts">
2+
import { FolderDownload } from '@icon-park/vue-next'
3+
import { useStorage } from '@vueuse/core'
4+
5+
const showKnowButton = useStorage('tip-drop-mask-button', true)
6+
</script>
7+
8+
<template>
9+
<div class="drop-mask">
10+
<FolderDownload size="32" />
11+
<h1>安装本地组件包</h1>
12+
<h3>将组件包.zip拖放到此处即可安装</h3>
13+
<el-button v-if="showKnowButton" type="primary" @click="showKnowButton = false">
14+
知道了
15+
</el-button>
16+
</div>
17+
</template>
18+
19+
<style scoped lang="scss">
20+
.drop-mask{
21+
position: absolute;
22+
top: 0;
23+
left: 0;
24+
width: 100%;
25+
color: white;
26+
display: flex;
27+
flex-direction: column;
28+
align-items: center;
29+
justify-content: center;
30+
height: 100%;
31+
z-index: 100;
32+
background: rgba(0, 0, 0, 0.4);
33+
backdrop-filter: blur(5px);
34+
gap: 12px;
35+
}
36+
h1{
37+
padding: 0;
38+
margin: 0;
39+
}
40+
h3{
41+
padding: 0;
42+
margin: 0;
43+
}
44+
</style>

0 commit comments

Comments
 (0)