@blocklet/ui-react 2.12.12 → 2.12.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/lib/@types/index.d.ts +2 -1
  2. package/lib/@types/index.js +1 -0
  3. package/lib/Footer/links.js +2 -1
  4. package/lib/Header/index.js +2 -1
  5. package/lib/UserCenter/components/editable-field.d.ts +2 -1
  6. package/lib/UserCenter/components/editable-field.js +5 -1
  7. package/lib/UserCenter/components/status-dialog/date-picker.d.ts +10 -0
  8. package/lib/UserCenter/components/status-dialog/date-picker.js +52 -0
  9. package/lib/UserCenter/components/status-dialog/index.d.ts +12 -0
  10. package/lib/UserCenter/components/status-dialog/index.js +238 -0
  11. package/lib/UserCenter/components/status-selector/menu-item.d.ts +2 -0
  12. package/lib/UserCenter/components/user-center.js +8 -3
  13. package/lib/UserCenter/components/user-info/clock.js +3 -2
  14. package/lib/UserCenter/components/user-info/metadata.js +15 -62
  15. package/lib/UserCenter/components/user-info/timezone-select.d.ts +8 -0
  16. package/lib/UserCenter/components/user-info/timezone-select.js +99 -0
  17. package/lib/UserCenter/components/user-info/user-basic-info.js +4 -14
  18. package/lib/UserCenter/components/user-info/user-status.d.ts +2 -1
  19. package/lib/UserCenter/components/user-info/user-status.js +49 -14
  20. package/lib/UserCenter/components/user-info/utils.d.ts +23 -0
  21. package/lib/UserCenter/components/user-info/utils.js +25 -1
  22. package/lib/UserCenter/libs/locales.d.ts +12 -0
  23. package/lib/UserCenter/libs/locales.js +18 -6
  24. package/lib/blocklets.js +7 -9
  25. package/package.json +4 -4
  26. package/src/@types/index.ts +1 -0
  27. package/src/Footer/links.jsx +2 -1
  28. package/src/Header/index.tsx +7 -1
  29. package/src/UserCenter/components/editable-field.tsx +6 -0
  30. package/src/UserCenter/components/status-dialog/date-picker.tsx +67 -0
  31. package/src/UserCenter/components/status-dialog/index.tsx +280 -0
  32. package/src/UserCenter/components/status-selector/menu-item.tsx +2 -0
  33. package/src/UserCenter/components/user-center.tsx +7 -2
  34. package/src/UserCenter/components/user-info/clock.tsx +3 -2
  35. package/src/UserCenter/components/user-info/metadata.tsx +17 -70
  36. package/src/UserCenter/components/user-info/timezone-select.tsx +114 -0
  37. package/src/UserCenter/components/user-info/user-basic-info.tsx +4 -11
  38. package/src/UserCenter/components/user-info/user-status.tsx +57 -13
  39. package/src/UserCenter/components/user-info/utils.ts +29 -1
  40. package/src/UserCenter/libs/locales.ts +14 -2
  41. package/src/blocklets.js +7 -9
@@ -2,7 +2,7 @@
2
2
  import Badge from '@mui/material/Badge';
3
3
  import Box from '@mui/material/Box';
4
4
  import styled from '@emotion/styled';
5
- import { lazy, useCallback, useEffect, useMemo, useState } from 'react';
5
+ import { lazy, Suspense, useCallback, useEffect, useMemo, useState } from 'react';
6
6
  import { useCreation, useMemoizedFn, useInterval, useUnmount } from 'ahooks';
7
7
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
8
8
  import Tooltip from '@mui/material/Tooltip';
@@ -11,9 +11,10 @@ import { SvgIconProps } from '@mui/material/SvgIcon';
11
11
  import { formatToDatetime } from '@arcblock/ux/lib/Util';
12
12
  import type { UserMetadata } from '../../../@types';
13
13
  import { DurationEnum, StatusEnum } from '../../../@types';
14
- import StatusSelector from '../status-selector';
14
+ import StatusDialog from '../status-dialog';
15
15
  import { translations } from '../../libs/locales';
16
16
  import { getTimeRemaining, isWithinTimeRange } from './utils';
17
+ import { StatusItem } from '../status-selector/menu-item';
17
18
 
18
19
  const MeetingIcon = lazy(() => import('@arcblock/icons/lib/Meeting'));
19
20
  const CommunityIcon = lazy(() => import('@arcblock/icons/lib/Community'));
@@ -29,18 +30,43 @@ const StatusIconMap: Record<StatusEnum, React.FC<SvgIconProps> | undefined> = {
29
30
  [StatusEnum.WorkingRemotely]: WorkingRemotelyIcon,
30
31
  };
31
32
 
33
+ const QuickSettings = {
34
+ [StatusEnum.Meeting]: {
35
+ duration: DurationEnum.OneHour,
36
+ durationName: 'userStatus.duration.OneHour',
37
+ },
38
+ [StatusEnum.Community]: {
39
+ duration: DurationEnum.ThirtyMinutes,
40
+ durationName: 'userStatus.duration.ThirtyMinutes',
41
+ },
42
+ [StatusEnum.Holiday]: {
43
+ duration: DurationEnum.ThisWeek,
44
+ durationName: 'userStatus.duration.ThisWeek',
45
+ },
46
+ [StatusEnum.OffSick]: {
47
+ duration: DurationEnum.Today,
48
+ durationName: 'userStatus.duration.Today',
49
+ },
50
+ [StatusEnum.WorkingRemotely]: {
51
+ duration: DurationEnum.ThisWeek,
52
+ durationName: 'userStatus.duration.ThisWeek',
53
+ },
54
+ };
55
+
32
56
  export default function UserStatus({
33
57
  isMobile,
34
58
  size,
35
59
  isMyself,
36
60
  status,
37
61
  onChange,
62
+ timezone,
38
63
  }: {
39
64
  isMobile?: boolean;
40
65
  size: number;
41
66
  isMyself: boolean;
42
67
  status: UserMetadata['status'];
43
68
  onChange: (v: UserMetadata['status']) => void;
69
+ timezone?: string;
44
70
  }) {
45
71
  const { locale } = useLocaleContext();
46
72
  const t = useMemoizedFn((key, data = {}) => {
@@ -94,12 +120,17 @@ export default function UserStatus({
94
120
 
95
121
  const statusData = useCreation(() => {
96
122
  const durationData = getDurationData();
97
- return Object.keys(StatusEnum).map((key) => ({
98
- id: StatusEnum[key as keyof typeof StatusEnum],
99
- name: t(`userStatus.${key}`),
100
- icon: StatusIconMap[StatusEnum[key as keyof typeof StatusEnum]],
101
- children: durationData,
102
- }));
123
+ return Object.keys(StatusEnum).map((key) => {
124
+ const quickSetting = QuickSettings[StatusEnum[key as keyof typeof StatusEnum]];
125
+
126
+ return {
127
+ id: StatusEnum[key as keyof typeof StatusEnum],
128
+ name: t(`userStatus.${key}`),
129
+ icon: StatusIconMap[StatusEnum[key as keyof typeof StatusEnum]],
130
+ ...(quickSetting ? { duration: quickSetting.duration, durationName: t(quickSetting.durationName) } : {}),
131
+ children: durationData,
132
+ };
133
+ });
103
134
  }, [t, getDurationData]);
104
135
 
105
136
  const onOpenStatusSelector = (event: React.MouseEvent<HTMLDivElement>) => {
@@ -117,9 +148,7 @@ export default function UserStatus({
117
148
  if (!isMyself) {
118
149
  return;
119
150
  }
120
- if (v) {
121
- onChange(v);
122
- }
151
+ onChange(v);
123
152
  onCloseStatusSelector();
124
153
  };
125
154
 
@@ -148,10 +177,25 @@ export default function UserStatus({
148
177
  alignItems="center"
149
178
  justifyContent="center"
150
179
  onClick={onOpenStatusSelector}>
151
- {StatusIcon ? <StatusIcon style={{ width: 16, height: 16 }} /> : <Badge color="success" variant="dot" />}
180
+ {StatusIcon ? (
181
+ <Suspense fallback={null}>
182
+ <StatusIcon style={{ width: 16, height: 16 }} />
183
+ </Suspense>
184
+ ) : (
185
+ <Badge color="success" variant="dot" />
186
+ )}
152
187
  </Box>
153
188
  </Tooltip>
154
- <StatusSelector selected={status} data={statusData} open={open} onSelect={onStatusChange} anchorEl={anchorEl} />
189
+ {open && (
190
+ <StatusDialog
191
+ selected={status}
192
+ data={statusData as StatusItem[]}
193
+ open={open}
194
+ onSelect={onStatusChange}
195
+ onClose={onCloseStatusSelector}
196
+ timezone={timezone}
197
+ />
198
+ )}
155
199
  </StatusDiv>
156
200
  );
157
201
  }
@@ -1,5 +1,6 @@
1
1
  import moment from 'moment-timezone';
2
2
  import dayjs from 'dayjs';
3
+ import { temp as colors } from '@arcblock/ux/lib/Colors';
3
4
  import { DurationEnum, UserMetadata } from '../../../@types';
4
5
 
5
6
  const HOUR = 3600;
@@ -8,6 +9,9 @@ const MINUTES_10 = 600;
8
9
  const MINUTES_5 = 300;
9
10
  const MINUTES_1 = 60;
10
11
  const SECOND = 1;
12
+
13
+ export const currentTimezone = moment.tz.guess();
14
+
11
15
  export const getTimezones = () => {
12
16
  const timezones = moment.tz.names();
13
17
 
@@ -46,7 +50,7 @@ export const isValidUrl = (url: string) => {
46
50
  * @returns
47
51
  */
48
52
  export const getStatusDuration = (status: UserMetadata['status']) => {
49
- let dateRange: dayjs.Dayjs[] = [];
53
+ let dateRange: dayjs.Dayjs[] = status?.dateRange?.map((d) => dayjs(d)) ?? [];
50
54
  const current = dayjs();
51
55
  switch (status?.duration) {
52
56
  case DurationEnum.ThirtyMinutes:
@@ -112,3 +116,27 @@ export const getTimeRemaining = (date: Date) => {
112
116
 
113
117
  return 0; // 如果时间已过期,返回0
114
118
  };
119
+
120
+ export const defaultButtonStyle = {
121
+ color: colors.foregroundsFgBase,
122
+ borderColor: colors.strokeBorderBase,
123
+ backgroundColor: colors.buttonsButtonNeutral,
124
+ '&:hover': {
125
+ borderColor: colors.strokeBorderBase,
126
+ backgroundColor: colors.buttonsButtonNeutralHover,
127
+ },
128
+ py: 0.5,
129
+ borderRadius: '8px',
130
+ };
131
+
132
+ export const primaryButtonStyle = {
133
+ color: colors.buttonsButtonNeutral,
134
+ borderColor: colors.foregroundsFgInteractive,
135
+ backgroundColor: colors.foregroundsFgInteractive,
136
+ '&:hover': {
137
+ borderColor: colors.foregroundsFgInteractive,
138
+ backgroundColor: colors.foregroundsFgInteractive,
139
+ },
140
+ py: 0.5,
141
+ borderRadius: '8px',
142
+ };
@@ -112,12 +112,14 @@ export const translations = {
112
112
  FourHours: '4小时',
113
113
  Today: '今天',
114
114
  ThisWeek: '本周',
115
+ Custom: '自定义时间',
115
116
  },
116
117
  },
117
118
  profile: {
118
119
  addLink: '添加连接',
119
120
  location: '位置',
120
121
  timezone: '时区',
122
+ bio: '个人简介',
121
123
  setStatus: '设置状态',
122
124
  localTime: '当地时间:',
123
125
  email: '邮箱地址',
@@ -125,8 +127,12 @@ export const translations = {
125
127
  phone: '电话号码',
126
128
  phoneInvalid: '电话号码格式不正确',
127
129
  editProfile: '编辑资料',
128
- removeStatusAfter: '移除状态',
130
+ removeStatusAfter: '在...之后移除状态',
129
131
  justForYou: '仅对您可见',
132
+ cleanStatus: '清除状态',
133
+ quickSettings: '快捷设置',
134
+ selectEndTime: '选择结束时间',
135
+ pleaseSelectTime: '请选择时间',
130
136
  },
131
137
  },
132
138
  en: {
@@ -242,12 +248,14 @@ export const translations = {
242
248
  FourHours: '4 hours',
243
249
  Today: 'Today',
244
250
  ThisWeek: 'This Week',
251
+ Custom: 'Custom',
245
252
  },
246
253
  },
247
254
  profile: {
248
255
  addLink: 'Add link',
249
256
  location: 'Location',
250
257
  timezone: 'Timezone',
258
+ bio: 'Bio',
251
259
  setStatus: 'Set a Status',
252
260
  localTime: 'Local Time: ',
253
261
  email: 'Email',
@@ -255,9 +263,13 @@ export const translations = {
255
263
  phone: 'Phone',
256
264
  phoneInvalid: 'Phone number is invalid',
257
265
  editProfile: 'Edit Profile',
258
- removeStatusAfter: 'Remove status after',
266
+ removeStatusAfter: 'Remove status after...',
259
267
  justForYou: 'Visible to you only',
260
268
  maxInputLength: 'Max input length is',
269
+ selectEndTime: 'Select end time',
270
+ pleaseSelectTime: 'Please select time',
271
+ cleanStatus: 'Clean status',
272
+ quickSettings: 'Quick Settings',
261
273
  },
262
274
  },
263
275
  };
package/src/blocklets.js CHANGED
@@ -45,15 +45,12 @@ export const getLocalizedNavigation = (navigation, locale = 'en') => {
45
45
  if (!navigation?.length) {
46
46
  return navigation;
47
47
  }
48
- // eslint-disable-next-line no-shadow
49
- const getTitle = (title, _locale) => {
50
- if (typeof title === 'string') {
51
- return title;
48
+ const trans = (text, _locale) => {
49
+ if (text && typeof text === 'object') {
50
+ return text[_locale] || text?.en || text?.zh;
52
51
  }
53
- if (typeof title === 'object') {
54
- return title[_locale] || title?.en || title?.zh;
55
- }
56
- return title;
52
+
53
+ return text;
57
54
  };
58
55
 
59
56
  return mapRecursive(
@@ -61,7 +58,8 @@ export const getLocalizedNavigation = (navigation, locale = 'en') => {
61
58
  (item) => {
62
59
  return {
63
60
  ...item,
64
- title: getTitle(item.title, locale),
61
+ title: trans(item.title, locale),
62
+ description: trans(item.description, locale),
65
63
  // 仅对叶结点进行处理
66
64
  link: !item.items?.length ? getLink(item.link, locale) : item.link,
67
65
  _rawLink: item.link,