Skip to content

Commit b4f27f9

Browse files
committed
细节调整
1 parent c4e7079 commit b4f27f9

28 files changed

+641
-340
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ widgets
4141
### 运行项目
4242

4343
#### Vue
44-
44+
#
4545
```shell
4646
pnpm serve
4747
```
4848

4949
#### Storybook
50-
50+
用StoryBook运行只能查看组件
5151
```shell
5252
pnpm storybook
5353
```

components.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ declare module '@vue/runtime-core' {
1414
ElFormItem: typeof import('element-plus/es')['ElFormItem']
1515
ElInput: typeof import('element-plus/es')['ElInput']
1616
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
17+
ElProgress: typeof import('element-plus/es')['ElProgress']
1718
ElRadio: typeof import('element-plus/es')['ElRadio']
1819
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
1920
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
"@vueuse/core": "^9.4.0",
3030
"@vueuse/integrations": "^9.6.0",
3131
"@vueuse/motion": "2.0.0-beta.12",
32-
"@widget-js/core": "^0.1.16",
32+
"@vueuse/router": "^9.9.0",
33+
"@widget-js/core": "^0.1.18",
3334
"@widget-js/vue3": "^0.1.18",
3435
"animate.css": "^4.1.1",
3536
"axios": "^1.1.3",

src/common/css/common.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ page view {
66
}
77

88
body {
9-
font-family: PingFangSC-Regular, Roboto, Helvetica Neue, Helvetica, Tahoma,
9+
font-family: Roboto, Helvetica Neue, Helvetica, Tahoma,
1010
Arial, PingFang SC-Light, Microsoft YaHei;
1111
margin: 0;
1212
overflow: hidden;
+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<template>
2+
<div class="break-view">
3+
<div class="countdown">
4+
<template v-for="(item,index) in array">
5+
<text-switcher :text="item" :font-size="item === ':' ? 150:300"/>
6+
</template>
7+
</div>
8+
<p>按Esc退出</p>
9+
</div>
10+
</template>
11+
12+
<script lang="ts">
13+
import {onKeyStroke, useIntervalFn} from "@vueuse/core";
14+
import {ref} from "vue";
15+
import TextSwitcher from "@/widgets/dynamic-island/components/TextSwitcher.vue";
16+
import '@/common/dayjs-extend'
17+
import dayjs from "dayjs";
18+
import {useRouteHash, useRouteQuery} from "@vueuse/router";
19+
20+
export default {
21+
name: "BreakView",
22+
components: {TextSwitcher},
23+
setup() {
24+
const i = ref(0);
25+
const duration = useRouteQuery('duration', `${5 * 60}`);
26+
console.log(window.location);
27+
console.log(duration);
28+
const targetTime = dayjs().add(parseInt(duration.value), 'second');
29+
const array = ref<string[]>();
30+
useIntervalFn(() => {
31+
const remindDuration = dayjs.duration(targetTime.diff(dayjs()))
32+
if (remindDuration.asSeconds() <= 0) {
33+
window.close()
34+
}
35+
const timeStr = remindDuration.format("mm:ss");
36+
array.value = timeStr.split('');
37+
i.value++;
38+
}, 1000, {immediate: true});
39+
40+
onKeyStroke('Escape', (e) => {
41+
window.close();
42+
})
43+
return {array}
44+
}
45+
}
46+
</script>
47+
48+
<style scoped lang="scss">
49+
50+
.break-view {
51+
color: white;
52+
background-color: rgba(0, 0, 0, 0.8);
53+
position: absolute;
54+
width: 100%;
55+
height: 100%;
56+
display: flex;
57+
justify-items: center;
58+
justify-content: center;
59+
align-content: center;
60+
align-items: center;
61+
flex-direction: column;
62+
63+
.text-switcher {
64+
color: white;
65+
}
66+
67+
.countdown {
68+
display: flex;
69+
flex-direction: row;
70+
align-items: center;
71+
letter-spacing: 16px;
72+
font-weight: bold;
73+
outline: none;
74+
75+
.number {
76+
font-size: 258px;
77+
}
78+
79+
.colon {
80+
font-size: 128px;
81+
}
82+
}
83+
84+
}
85+
</style>

src/widgets/dynamic-island/DynamicIsland.widget.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {Widget, WidgetKeyword} from "@widget-js/core";
22
//TODO 修改组件信息,标题,描述,关键词
33
const name = "cn.widgetjs.widgets.dynamic_island";
44
//组件标题
5-
const title = {"zh": "灵动岛"};
5+
const title = {"zh": "灵动通知"};
66
//组件描述
77
const description = {"zh": "丝般顺滑的灵动通知组件"};
88
//组件关键词

src/widgets/dynamic-island/DynamicIslandConfigView.vue

+3-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
@confirm="onSaveClick()">
66
<template v-slot:form>
77
<widget-checkbox-field v-model:checked="widgetData.enable" label="启用久坐提醒"/>
8-
<widget-slider-field v-model:value="widgetData.sitInterval" label="久坐时长(分钟)" :min="5" :max="120"/>
8+
<widget-slider-field v-model:value="widgetData.sitInterval" label="久坐时长(分钟)" :min="1" :max="120"/>
99
<widget-slider-field v-model:value="widgetData.breakInterval" label="休息时长(分钟)" :min="1" :max="60"/>
10-
<widget-slider-field v-model:value="widgetData.usageInterval" label="检测阈值(分钟)" :min="1" :max="120"/>
10+
<widget-slider-field v-model:value="widgetData.mouseCheckInterval" label="检测阈值(分钟)" :min="1" :max="120"/>
1111
<el-alert type="info" :closable="false">
1212
<p>检测阈值:多久没使用鼠标视为离开电脑</p>
1313
</el-alert>
@@ -27,7 +27,7 @@ export default {
2727
name: "",
2828
components: {DynamicIslandWidget, WidgetEditDialog},
2929
setup() {
30-
const name = "cn.widgetjs.widget.dynamic_island.sit_reminder";
30+
const name = "cn.widgetjs.widget.sit_reminder";
3131
const sitReminder = new SitReminder(name);
3232
const {widgetData, widgetParams} = useWidget(SitReminder, {
3333
defaultData: sitReminder,
@@ -47,7 +47,6 @@ export default {
4747
methods: {
4848
async onSaveClick() {
4949
await WidgetApi.saveDataByName(this.widgetData);
50-
NotificationApi.info(this.widgetData.breakInterval)
5150
window.close();
5251
}
5352
}

src/widgets/dynamic-island/DynamicIslandWidget.stories.ts

+3-18
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import DynamicIslandWidget from './DynamicIslandWidget.vue';
22
import dayjs from "dayjs";
33
import {NotificationState} from "@/widgets/dynamic-island/model/NotificationState";
4-
import {NotificationType} from "@widget-js/core";
4+
import {AdvanceCountdownDemo, SitReminderDemo} from "@/widgets/dynamic-island/model/Demo";
55

66
export default {
77
title: 'Widget/DynamicIsland',
@@ -78,13 +78,7 @@ Countdown.args = {
7878
export const CountdownAdvance = Template.bind({})
7979
// @ts-ignore
8080
CountdownAdvance.args = {
81-
notification: {
82-
type: 'advance-countdown',
83-
title: "新年倒计时",
84-
message: '恭喜发财',
85-
backgroundColor: "rgba(0,0,0,0.5)",
86-
targetTime: date.toISOString(),
87-
},
81+
notification: AdvanceCountdownDemo,
8882
state: NotificationState.NORMAL,
8983
}
9084

@@ -93,14 +87,5 @@ export const Reminder = Template.bind({})
9387
// @ts-ignore
9488
Reminder.args = {
9589
state: NotificationState.LARGE,
96-
notification: {
97-
type: "reminder",
98-
message: '您已经连续使用电脑45分钟',
99-
state: NotificationState.LARGE,
100-
title: '久坐提醒',
101-
icon: 'computer_line',
102-
color: '#5D8AC8',
103-
cancelButtonText:"知道了",
104-
confirmButtonText:"休息一下",
105-
}
90+
notification: SitReminderDemo
10691
}

src/widgets/dynamic-island/DynamicIslandWidget.vue

+35-47
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
<advance-countdown-notification v-else-if="notification.type === 'advance-countdown'" v-bind="notification"/>
66
<custom-url-notification v-else-if="notification.type === 'url'" v-bind="notification"/>
77
<reminder-notification v-else-if="notification.type === 'reminder'" :notification="notification"/>
8-
<phone-call-notification ref="phoneCall" v-else-if="notification.type === 'call'" v-bind="notification"/>
8+
<phone-call-notification :key="notification.createdAt" ref="phoneCall" v-else-if="notification.type === 'call'"
9+
v-bind="notification"/>
910
<message-notification v-else v-bind="notification"/>
1011
</div>
1112
</template>
@@ -20,7 +21,7 @@ import CustomUrlNotification from "@/widgets/dynamic-island/components/CustomUrl
2021
import ReminderNotification from "@/widgets/dynamic-island/components/ReminderNotification.vue";
2122
import {NotificationState} from "@/widgets/dynamic-island/model/NotificationState";
2223
import {useMotion} from "@vueuse/motion";
23-
import {SwipeDirection, usePointerSwipe} from "@vueuse/core";
24+
import {SwipeDirection, useDraggable, useIntervalFn, usePointerSwipe} from "@vueuse/core";
2425
import {AppNotification} from "@widget-js/core";
2526
2627
export default {
@@ -31,7 +32,7 @@ export default {
3132
MessageNotification,
3233
AdvanceCountdownNotification, CountingNotification, PhoneCallNotification
3334
},
34-
emits: ["mouseEnter", "mouseLeave", "hidden", "update:state"],
35+
emits: ["mouseEnter", "mouseLeave", "update:state"],
3536
setup(props, context) {
3637
const container = ref();
3738
const backgroundColor = ref("black");
@@ -52,15 +53,23 @@ export default {
5253
height: 48,
5354
scale: 1,
5455
backgroundColor: backgroundColor,
55-
transition
56+
transition: {
57+
duration: 500,
58+
type: 'keyframe',
59+
onComplete: () => {
60+
},
61+
}
5662
}
57-
const {apply, motionProperties} = useMotion(island, {
58-
initial: {...hide},
63+
const {apply, motionProperties, variant} = useMotion(island, {
64+
initial: {...hide,},
5965
hide,
6066
tapped: {
6167
scale: 0.95,
6268
backgroundColor: backgroundColor,
63-
transition
69+
transition: {
70+
...transition,
71+
onComplete: () => (variant.value = 'hovered'),
72+
}
6473
},
6574
hovered: {
6675
scale: 1,
@@ -92,26 +101,24 @@ export default {
92101
transition
93102
},
94103
});
95-
watch(motionProperties, () => {
96-
if (motionProperties['y'] < minY) {
97-
context.emit('hidden');
98-
if (phoneCall) {
99-
phoneCall.value?.stop();
100-
}
101-
}
102-
})
103104
const stateModel = computed({
104105
get: () => {
105106
return props.state
106107
},
107108
set: (value) => {
108109
apply(value);
110+
if (value == NotificationState.HIDE) {
111+
if (phoneCall) {
112+
phoneCall.value?.stop();
113+
}
114+
}
109115
context.emit('update:state', value);
110116
}
111117
})
112118
let startTranslateY = -100;
113-
const {distanceY} = usePointerSwipe(island, {
114-
onSwipeStart() {
119+
const {distanceY, isSwiping, stop: stopSwipe} = usePointerSwipe(island, {
120+
threshold: 10,
121+
onSwipeStart(e) {
115122
startTranslateY = motionProperties['y'];
116123
},
117124
async onSwipe(e: PointerEvent) {
@@ -126,20 +133,19 @@ export default {
126133
})
127134
},
128135
async onSwipeEnd(e: PointerEvent, direction: SwipeDirection) {
129-
console.log(motionProperties['y'])
130136
if (motionProperties['y'] < 0) {
131137
stateModel.value = NotificationState.HIDE;
132138
} else {
133139
await apply(stateModel.value)
134140
}
135141
},
136142
});
137-
return {container, phoneCall, backgroundColor, island, stateModel, apply}
143+
return {container, phoneCall, isSwiping, variant, backgroundColor, island, stateModel, apply}
138144
},
139145
methods: {},
140146
async mounted() {
141147
await nextTick();
142-
this.apply(this.state);
148+
await this.apply(this.state);
143149
},
144150
watch: {
145151
state(newState) {
@@ -168,6 +174,8 @@ export default {
168174
<style scoped lang="scss">
169175
$cubic-bezier: cubic-bezier(0, 1, .68, 1.05);
170176
.island {
177+
-webkit-font-smoothing: antialiased;
178+
user-select: none;
171179
cursor: pointer;
172180
border-radius: 42px;
173181
display: flex;
@@ -176,40 +184,20 @@ $cubic-bezier: cubic-bezier(0, 1, .68, 1.05);
176184
right: 0;
177185
margin: auto;
178186
background-color: black;
179-
transition-property: width, height;
180-
transition-duration: 0.8s;
181-
transition-timing-function: $cubic-bezier;
182187
will-change: width, height;
183188
clip: auto;
184189
overflow: hidden;
185190
justify-content: flex-start;
186191
box-shadow: (0px 12px 32px 4px rgba(0, 0, 0, 0.04), 0px 8px 20px rgba(0, 0, 0, 0.08));
187192
188-
.content {
189-
flex: 1;
190-
display: flex;
191-
192-
align-items: flex-start;
193-
margin-left: 1rem;
194-
margin-right: 1rem;
193+
.mask {
194+
position: absolute;
195+
width: 100%;
195196
height: 100%;
196-
justify-content: space-around;
197-
flex-direction: column;
198-
199-
.title {
200-
font-size: 0.8em;
201-
color: rgba(255, 255, 255, 0.6);
202-
}
203-
204-
.description {
205-
color: white;
206-
font-size: 1em;
207-
}
208-
}
209-
210-
.actions {
211-
display: flex;
212-
justify-content: flex-start;
197+
z-index: 5;
198+
left: 0;
199+
top: 0;
200+
background-color: black;
213201
}
214202
}
215203
</style>

src/widgets/dynamic-island/DynamicIslandWidgetRoutes.ts

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ const DynamicIslandWidgetRoutes = [
2020
path: '/widget/dynamic_island/call',
2121
name: `${name}.call`,
2222
component: () => import(/* webpackChunkName: "com.wisdom.widgets.dynamic_island.call" */ './components/PhoneCallNotification.vue')
23+
},
24+
{
25+
path: '/widget/dynamic_island/break',
26+
name: `${name}.break`,
27+
component: () => import(/* webpackChunkName: "com.wisdom.widgets.dynamic_island.break" */ './BreakView.vue')
2328
}
2429
]
2530

0 commit comments

Comments
 (0)