Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
14f9f293
Unverified
Commit
14f9f293
authored
Dec 02, 2022
by
boojack
Committed by
GitHub
Dec 02, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: update user setting appearance (#654)
parent
5451fd2d
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
134 additions
and
159 deletions
+134
-159
user_setting.go
api/user_setting.go
+22
-1
App.tsx
web/src/App.tsx
+16
-3
AppearanceSelect.tsx
web/src/components/AppearanceSelect.tsx
+7
-5
DailyReviewDialog.tsx
web/src/components/DailyReviewDialog.tsx
+0
-1
PreferencesSection.tsx
web/src/components/Settings/PreferencesSection.tsx
+52
-19
ShareMemoImageDialog.tsx
web/src/components/ShareMemoImageDialog.tsx
+1
-4
storage.ts
web/src/helpers/storage.ts
+2
-0
utils.ts
web/src/helpers/utils.ts
+8
-0
useAppearance.ts
web/src/hooks/useAppearance.ts
+0
-65
useMediaQuery.ts
web/src/hooks/useMediaQuery.ts
+0
-21
useQuery.ts
web/src/hooks/useQuery.ts
+0
-13
daily-review-dialog.less
web/src/less/daily-review-dialog.less
+2
-2
share-memo-image-dialog.less
web/src/less/share-memo-image-dialog.less
+7
-15
globalService.ts
web/src/services/globalService.ts
+5
-2
userService.ts
web/src/services/userService.ts
+10
-6
global.ts
web/src/store/modules/global.ts
+1
-1
setting.d.ts
web/src/types/modules/setting.d.ts
+1
-1
No files found.
api/user_setting.go
View file @
14f9f293
...
@@ -10,6 +10,8 @@ type UserSettingKey string
...
@@ -10,6 +10,8 @@ type UserSettingKey string
const
(
const
(
// UserSettingLocaleKey is the key type for user locale.
// UserSettingLocaleKey is the key type for user locale.
UserSettingLocaleKey
UserSettingKey
=
"locale"
UserSettingLocaleKey
UserSettingKey
=
"locale"
// UserSettingAppearanceKey is the key type for user appearance.
UserSettingAppearanceKey
UserSettingKey
=
"appearance"
// UserSettingMemoVisibilityKey is the key type for user preference memo default visibility.
// UserSettingMemoVisibilityKey is the key type for user preference memo default visibility.
UserSettingMemoVisibilityKey
UserSettingKey
=
"memoVisibility"
UserSettingMemoVisibilityKey
UserSettingKey
=
"memoVisibility"
// UserSettingMemoDisplayTsOptionKey is the key type for memo display ts option.
// UserSettingMemoDisplayTsOptionKey is the key type for memo display ts option.
...
@@ -21,6 +23,8 @@ func (key UserSettingKey) String() string {
...
@@ -21,6 +23,8 @@ func (key UserSettingKey) String() string {
switch
key
{
switch
key
{
case
UserSettingLocaleKey
:
case
UserSettingLocaleKey
:
return
"locale"
return
"locale"
case
UserSettingAppearanceKey
:
return
"appearance"
case
UserSettingMemoVisibilityKey
:
case
UserSettingMemoVisibilityKey
:
return
"memoVisibility"
return
"memoVisibility"
case
UserSettingMemoDisplayTsOptionKey
:
case
UserSettingMemoDisplayTsOptionKey
:
...
@@ -31,8 +35,8 @@ func (key UserSettingKey) String() string {
...
@@ -31,8 +35,8 @@ func (key UserSettingKey) String() string {
var
(
var
(
UserSettingLocaleValue
=
[]
string
{
"en"
,
"zh"
,
"vi"
,
"fr"
}
UserSettingLocaleValue
=
[]
string
{
"en"
,
"zh"
,
"vi"
,
"fr"
}
UserSettingAppearanceValue
=
[]
string
{
"light"
,
"dark"
}
UserSettingMemoVisibilityValue
=
[]
Visibility
{
Private
,
Protected
,
Public
}
UserSettingMemoVisibilityValue
=
[]
Visibility
{
Private
,
Protected
,
Public
}
UserSettingEditorFontStyleValue
=
[]
string
{
"normal"
,
"mono"
}
UserSettingMemoDisplayTsOptionKeyValue
=
[]
string
{
"created_ts"
,
"updated_ts"
}
UserSettingMemoDisplayTsOptionKeyValue
=
[]
string
{
"created_ts"
,
"updated_ts"
}
)
)
...
@@ -67,6 +71,23 @@ func (upsert UserSettingUpsert) Validate() error {
...
@@ -67,6 +71,23 @@ func (upsert UserSettingUpsert) Validate() error {
if
invalid
{
if
invalid
{
return
fmt
.
Errorf
(
"invalid user setting locale value"
)
return
fmt
.
Errorf
(
"invalid user setting locale value"
)
}
}
}
else
if
upsert
.
Key
==
UserSettingAppearanceKey
{
appearanceValue
:=
"light"
err
:=
json
.
Unmarshal
([]
byte
(
upsert
.
Value
),
&
appearanceValue
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to unmarshal user setting appearance value"
)
}
invalid
:=
true
for
_
,
value
:=
range
UserSettingAppearanceValue
{
if
appearanceValue
==
value
{
invalid
=
false
break
}
}
if
invalid
{
return
fmt
.
Errorf
(
"invalid user setting appearance value"
)
}
}
else
if
upsert
.
Key
==
UserSettingMemoVisibilityKey
{
}
else
if
upsert
.
Key
==
UserSettingMemoVisibilityKey
{
memoVisibilityValue
:=
Private
memoVisibilityValue
:=
Private
err
:=
json
.
Unmarshal
([]
byte
(
upsert
.
Value
),
&
memoVisibilityValue
)
err
:=
json
.
Unmarshal
([]
byte
(
upsert
.
Value
),
&
memoVisibilityValue
)
...
...
web/src/App.tsx
View file @
14f9f293
...
@@ -6,12 +6,12 @@ import { useAppSelector } from "./store";
...
@@ -6,12 +6,12 @@ import { useAppSelector } from "./store";
import
Loading
from
"./pages/Loading"
;
import
Loading
from
"./pages/Loading"
;
import
router
from
"./router"
;
import
router
from
"./router"
;
import
*
as
storage
from
"./helpers/storage"
;
import
*
as
storage
from
"./helpers/storage"
;
import
useAppearance
from
"./hooks/useAppearance
"
;
import
{
useColorScheme
}
from
"@mui/joy
"
;
function
App
()
{
function
App
()
{
const
{
i18n
}
=
useTranslation
();
const
{
i18n
}
=
useTranslation
();
const
{
locale
,
systemStatus
}
=
useAppSelector
((
state
)
=>
state
.
global
);
const
{
appearance
,
locale
,
systemStatus
}
=
useAppSelector
((
state
)
=>
state
.
global
);
useAppearanc
e
();
const
{
setMode
}
=
useColorSchem
e
();
useEffect
(()
=>
{
useEffect
(()
=>
{
locationService
.
updateStateWithLocation
();
locationService
.
updateStateWithLocation
();
...
@@ -42,6 +42,19 @@ function App() {
...
@@ -42,6 +42,19 @@ function App() {
});
});
},
[
locale
]);
},
[
locale
]);
useEffect
(()
=>
{
const
root
=
document
.
documentElement
;
if
(
appearance
===
"light"
)
{
root
.
classList
.
remove
(
"dark"
);
}
else
if
(
appearance
===
"dark"
)
{
root
.
classList
.
add
(
"dark"
);
}
setMode
(
appearance
);
storage
.
set
({
appearance
:
appearance
,
});
},
[
appearance
]);
return
(
return
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
RouterProvider
router=
{
router
}
/>
<
RouterProvider
router=
{
router
}
/>
...
...
web/src/components/AppearanceSelect.tsx
View file @
14f9f293
import
{
Option
,
Select
}
from
"@mui/joy"
;
import
{
Option
,
Select
}
from
"@mui/joy"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
globalService
}
from
"../services"
;
import
{
globalService
,
userService
}
from
"../services"
;
import
{
useAppSelector
}
from
"../store"
;
import
{
useAppSelector
}
from
"../store"
;
import
Icon
from
"./Icon"
;
import
Icon
from
"./Icon"
;
const
appearanceList
=
[
"
system"
,
"
light"
,
"dark"
];
const
appearanceList
=
[
"light"
,
"dark"
];
const
AppearanceSelect
=
()
=>
{
const
AppearanceSelect
=
()
=>
{
const
user
=
useAppSelector
((
state
)
=>
state
.
user
.
user
);
const
appearance
=
useAppSelector
((
state
)
=>
state
.
global
.
appearance
);
const
appearance
=
useAppSelector
((
state
)
=>
state
.
global
.
appearance
);
const
{
t
}
=
useTranslation
();
const
{
t
}
=
useTranslation
();
...
@@ -16,12 +17,13 @@ const AppearanceSelect = () => {
...
@@ -16,12 +17,13 @@ const AppearanceSelect = () => {
return
<
Icon
.
Sun
className=
{
className
}
/>;
return
<
Icon
.
Sun
className=
{
className
}
/>;
}
else
if
(
apperance
===
"dark"
)
{
}
else
if
(
apperance
===
"dark"
)
{
return
<
Icon
.
Moon
className=
{
className
}
/>;
return
<
Icon
.
Moon
className=
{
className
}
/>;
}
else
{
return
<
Icon
.
Smile
className=
{
className
}
/>;
}
}
};
};
const
handleSelectChange
=
(
appearance
:
Appearance
)
=>
{
const
handleSelectChange
=
async
(
appearance
:
Appearance
)
=>
{
if
(
user
)
{
await
userService
.
upsertUserSetting
(
"appearance"
,
appearance
);
}
globalService
.
setAppearance
(
appearance
);
globalService
.
setAppearance
(
appearance
);
};
};
...
...
web/src/components/DailyReviewDialog.tsx
View file @
14f9f293
...
@@ -43,7 +43,6 @@ const DailyReviewDialog: React.FC<Props> = (props: Props) => {
...
@@ -43,7 +43,6 @@ const DailyReviewDialog: React.FC<Props> = (props: Props) => {
toggleShowDatePicker
(
false
);
toggleShowDatePicker
(
false
);
toImage
(
memosElRef
.
current
,
{
toImage
(
memosElRef
.
current
,
{
backgroundColor
:
"#ffffff"
,
pixelRatio
:
window
.
devicePixelRatio
*
2
,
pixelRatio
:
window
.
devicePixelRatio
*
2
,
})
})
.
then
((
url
)
=>
{
.
then
((
url
)
=>
{
...
...
web/src/components/Settings/PreferencesSection.tsx
View file @
14f9f293
import
{
Select
,
Switch
,
Option
}
from
"@mui/joy"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
Switch
from
"@mui/joy/Switch"
;
import
{
globalService
,
userService
}
from
"../../services"
;
import
{
globalService
,
userService
}
from
"../../services"
;
import
{
useAppSelector
}
from
"../../store"
;
import
{
useAppSelector
}
from
"../../store"
;
import
{
VISIBILITY_SELECTOR_ITEMS
,
MEMO_DISPLAY_TS_OPTION_SELECTOR_ITEMS
}
from
"../../helpers/consts"
;
import
{
VISIBILITY_SELECTOR_ITEMS
,
MEMO_DISPLAY_TS_OPTION_SELECTOR_ITEMS
}
from
"../../helpers/consts"
;
import
Selector
from
"../common/Selector
"
;
import
Icon
from
"../Icon
"
;
import
AppearanceSelect
from
"../AppearanceSelect"
;
import
AppearanceSelect
from
"../AppearanceSelect"
;
import
"../../less/settings/preferences-section.less"
;
import
"../../less/settings/preferences-section.less"
;
...
@@ -63,32 +63,65 @@ const PreferencesSection = () => {
...
@@ -63,32 +63,65 @@ const PreferencesSection = () => {
return
(
return
(
<
div
className=
"section-container preferences-section-container"
>
<
div
className=
"section-container preferences-section-container"
>
<
p
className=
"title-text"
>
{
t
(
"common.basic"
)
}
</
p
>
<
p
className=
"title-text"
>
{
t
(
"common.basic"
)
}
</
p
>
<
label
className=
"form-label selector"
>
<
div
className=
"form-label selector"
>
<
span
className=
"normal-text"
>
{
t
(
"common.language"
)
}
</
span
>
<
span
className=
"normal-text"
>
{
t
(
"common.language"
)
}
</
span
>
<
Selector
className=
"ml-2 w-32"
value=
{
setting
.
locale
}
dataSource=
{
localeSelectorItems
}
handleValueChanged=
{
handleLocaleChanged
}
/>
<
Select
</
label
>
className=
"!min-w-[10rem] w-auto text-sm"
<
label
className=
"form-label selector"
>
value=
{
setting
.
locale
}
onChange=
{
(
_
,
locale
)
=>
{
if
(
locale
)
{
handleLocaleChanged
(
locale
);
}
}
}
startDecorator=
{
<
Icon
.
Globe
className=
"w-4 h-auto"
/>
}
>
{
localeSelectorItems
.
map
((
item
)
=>
(
<
Option
key=
{
item
.
value
}
value=
{
item
.
value
}
className=
"whitespace-nowrap"
>
{
item
.
text
}
</
Option
>
))
}
</
Select
>
</
div
>
<
div
className=
"form-label selector"
>
<
span
className=
"normal-text"
>
Theme
</
span
>
<
span
className=
"normal-text"
>
Theme
</
span
>
<
AppearanceSelect
/>
<
AppearanceSelect
/>
</
label
>
</
div
>
<
p
className=
"title-text"
>
{
t
(
"setting.preference"
)
}
</
p
>
<
p
className=
"title-text"
>
{
t
(
"setting.preference"
)
}
</
p
>
<
label
className=
"form-label selector"
>
<
div
className=
"form-label selector"
>
<
span
className=
"normal-text"
>
{
t
(
"setting.preference-section.default-memo-visibility"
)
}
</
span
>
<
span
className=
"normal-text"
>
{
t
(
"setting.preference-section.default-memo-visibility"
)
}
</
span
>
<
Select
or
<
Select
className=
"
ml-2 w-32
"
className=
"
!min-w-[10rem] w-auto text-sm
"
value=
{
setting
.
memoVisibility
}
value=
{
setting
.
memoVisibility
}
dataSource=
{
visibilitySelectorItems
}
onChange=
{
(
_
,
visibility
)
=>
{
handleValueChanged=
{
handleDefaultMemoVisibilityChanged
}
if
(
visibility
)
{
/>
handleDefaultMemoVisibilityChanged
(
visibility
);
</
label
>
}
}
}
>
{
visibilitySelectorItems
.
map
((
item
)
=>
(
<
Option
key=
{
item
.
value
}
value=
{
item
.
value
}
className=
"whitespace-nowrap"
>
{
item
.
text
}
</
Option
>
))
}
</
Select
>
</
div
>
<
label
className=
"form-label selector"
>
<
label
className=
"form-label selector"
>
<
span
className=
"normal-text"
>
{
t
(
"setting.preference-section.default-memo-sort-option"
)
}
</
span
>
<
span
className=
"normal-text"
>
{
t
(
"setting.preference-section.default-memo-sort-option"
)
}
</
span
>
<
Select
or
<
Select
className=
"
ml-2 w-32
"
className=
"
!min-w-[10rem] w-auto text-sm
"
value=
{
setting
.
memoDisplayTsOption
}
value=
{
setting
.
memoDisplayTsOption
}
dataSource=
{
memoDisplayTsOptionSelectorItems
}
onChange=
{
(
_
,
value
)
=>
{
handleValueChanged=
{
handleMemoDisplayTsOptionChanged
}
if
(
value
)
{
/>
handleMemoDisplayTsOptionChanged
(
value
);
}
}
}
>
{
memoDisplayTsOptionSelectorItems
.
map
((
item
)
=>
(
<
Option
key=
{
item
.
value
}
value=
{
item
.
value
}
className=
"whitespace-nowrap"
>
{
item
.
text
}
</
Option
>
))
}
</
Select
>
</
label
>
</
label
>
<
label
className=
"form-label selector"
>
<
label
className=
"form-label selector"
>
<
span
className=
"normal-text"
>
{
t
(
"setting.preference-section.enable-folding-memo"
)
}
</
span
>
<
span
className=
"normal-text"
>
{
t
(
"setting.preference-section.enable-folding-memo"
)
}
</
span
>
...
...
web/src/components/ShareMemoImageDialog.tsx
View file @
14f9f293
...
@@ -14,7 +14,6 @@ import toastHelper from "./Toast";
...
@@ -14,7 +14,6 @@ import toastHelper from "./Toast";
import
MemoContent
from
"./MemoContent"
;
import
MemoContent
from
"./MemoContent"
;
import
MemoResources
from
"./MemoResources"
;
import
MemoResources
from
"./MemoResources"
;
import
Selector
from
"./common/Selector"
;
import
Selector
from
"./common/Selector"
;
import
useAppearance
from
"../hooks/useAppearance"
;
import
"../less/share-memo-image-dialog.less"
;
import
"../less/share-memo-image-dialog.less"
;
interface
Props
extends
DialogProps
{
interface
Props
extends
DialogProps
{
...
@@ -36,7 +35,6 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
...
@@ -36,7 +35,6 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
shortcutImgUrl
:
""
,
shortcutImgUrl
:
""
,
memoVisibility
:
propsMemo
.
visibility
,
memoVisibility
:
propsMemo
.
visibility
,
});
});
const
[
appearance
]
=
useAppearance
();
const
loadingState
=
useLoading
();
const
loadingState
=
useLoading
();
const
memoElRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
memoElRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
memo
=
{
const
memo
=
{
...
@@ -72,7 +70,6 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
...
@@ -72,7 +70,6 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
}
}
toImage
(
memoElRef
.
current
,
{
toImage
(
memoElRef
.
current
,
{
backgroundColor
:
appearance
===
"light"
?
"#f4f4f5"
:
"#27272a"
,
pixelRatio
:
window
.
devicePixelRatio
*
2
,
pixelRatio
:
window
.
devicePixelRatio
*
2
,
})
})
.
then
((
url
)
=>
{
.
then
((
url
)
=>
{
...
@@ -147,7 +144,7 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
...
@@ -147,7 +144,7 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
<
div
className=
"userinfo-container"
>
<
div
className=
"userinfo-container"
>
<
span
className=
"name-text"
>
{
user
.
nickname
||
user
.
username
}
</
span
>
<
span
className=
"name-text"
>
{
user
.
nickname
||
user
.
username
}
</
span
>
<
span
className=
"usage-text"
>
<
span
className=
"usage-text"
>
{
createdDays
}
DAYS /
{
state
.
memoAmount
}
MEMO
S
{
state
.
memoAmount
}
MEMOS /
{
createdDays
}
DAY
S
</
span
>
</
span
>
</
div
>
</
div
>
<
img
className=
"logo-img"
src=
"/logo.webp"
alt=
""
/>
<
img
className=
"logo-img"
src=
"/logo.webp"
alt=
""
/>
...
...
web/src/helpers/storage.ts
View file @
14f9f293
...
@@ -10,6 +10,8 @@ interface StorageData {
...
@@ -10,6 +10,8 @@ interface StorageData {
editingMemoVisibilityCache
:
Visibility
;
editingMemoVisibilityCache
:
Visibility
;
// locale
// locale
locale
:
Locale
;
locale
:
Locale
;
// appearance
appearance
:
Appearance
;
// local setting
// local setting
localSetting
:
LocalSetting
;
localSetting
:
LocalSetting
;
// skipped version
// skipped version
...
...
web/src/helpers/utils.ts
View file @
14f9f293
...
@@ -140,3 +140,11 @@ export function absolutifyLink(rel: string): string {
...
@@ -140,3 +140,11 @@ export function absolutifyLink(rel: string): string {
anchor
.
setAttribute
(
"href"
,
rel
);
anchor
.
setAttribute
(
"href"
,
rel
);
return
anchor
.
href
;
return
anchor
.
href
;
}
}
export
function
getSystemColorScheme
()
{
if
(
window
.
matchMedia
&&
window
.
matchMedia
(
"(prefers-color-scheme: dark)"
).
matches
)
{
return
"dark"
;
}
else
{
return
"light"
;
}
}
web/src/hooks/useAppearance.ts
deleted
100644 → 0
View file @
5451fd2d
import
{
useEffect
}
from
"react"
;
import
{
useColorScheme
}
from
"@mui/joy/styles"
;
import
{
useAppSelector
}
from
"../store"
;
import
{
globalService
}
from
"../services"
;
const
getSystemColorScheme
=
()
=>
{
if
(
window
.
matchMedia
&&
window
.
matchMedia
(
"(prefers-color-scheme: dark)"
).
matches
)
{
return
"dark"
;
}
else
{
return
"light"
;
}
};
const
useAppearance
=
()
=>
{
const
user
=
useAppSelector
((
state
)
=>
state
.
user
.
user
);
const
appearance
=
useAppSelector
((
state
)
=>
state
.
global
.
appearance
);
const
{
mode
,
setMode
}
=
useColorScheme
();
useEffect
(()
=>
{
if
(
user
)
{
globalService
.
setAppearance
(
user
.
setting
.
appearance
);
}
},
[
user
]);
useEffect
(()
=>
{
let
mode
=
appearance
;
if
(
appearance
===
"system"
)
{
mode
=
getSystemColorScheme
();
}
setMode
(
mode
);
},
[
appearance
]);
useEffect
(()
=>
{
const
colorSchemeChangeHandler
=
(
event
:
MediaQueryListEvent
)
=>
{
const
newColorScheme
=
event
.
matches
?
"dark"
:
"light"
;
if
(
globalService
.
getState
().
appearance
===
"system"
)
{
setMode
(
newColorScheme
);
}
};
if
(
appearance
!==
"system"
)
{
window
.
matchMedia
(
"(prefers-color-scheme: dark)"
).
removeEventListener
(
"change"
,
colorSchemeChangeHandler
);
return
;
}
window
.
matchMedia
(
"(prefers-color-scheme: dark)"
).
addEventListener
(
"change"
,
colorSchemeChangeHandler
);
return
()
=>
{
window
.
matchMedia
(
"(prefers-color-scheme: dark)"
).
removeEventListener
(
"change"
,
colorSchemeChangeHandler
);
};
},
[
appearance
]);
useEffect
(()
=>
{
const
root
=
document
.
documentElement
;
if
(
mode
===
"dark"
)
{
root
.
classList
.
add
(
"dark"
);
}
else
if
(
mode
===
"light"
)
{
root
.
classList
.
remove
(
"dark"
);
}
},
[
mode
]);
return
[
appearance
,
globalService
.
setAppearance
]
as
const
;
};
export
default
useAppearance
;
web/src/hooks/useMediaQuery.ts
deleted
100644 → 0
View file @
5451fd2d
import
{
useState
,
useEffect
}
from
"react"
;
const
useMediaQuery
=
(
query
:
string
)
=>
{
const
[
matches
,
setMatches
]
=
useState
(
false
);
useEffect
(()
=>
{
const
media
=
window
.
matchMedia
(
query
);
if
(
media
.
matches
!==
matches
)
{
setMatches
(
media
.
matches
);
}
const
listener
=
()
=>
{
setMatches
(
media
.
matches
);
};
media
.
addEventListener
(
"change"
,
listener
);
return
()
=>
media
.
removeEventListener
(
"change"
,
listener
);
},
[
query
,
matches
]);
return
matches
;
};
export
default
useMediaQuery
;
web/src/hooks/useQuery.ts
deleted
100644 → 0
View file @
5451fd2d
// A custom hook that builds on useLocation to parse
import
React
from
"react"
;
import
{
useLocation
}
from
"react-router-dom"
;
// the query string for you.
const
useQuery
=
()
=>
{
const
{
search
}
=
useLocation
();
return
React
.
useMemo
(()
=>
new
URLSearchParams
(
search
),
[
search
]);
};
export
default
useQuery
;
web/src/less/daily-review-dialog.less
View file @
14f9f293
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
@apply p-0 sm:py-16;
@apply p-0 sm:py-16;
> .dialog-container {
> .dialog-container {
@apply w-full sm:w-112 max-w-full grow sm:grow-0 p-0 rounded-none sm:rounded-lg;
@apply w-full sm:w-112 max-w-full grow sm:grow-0 p-0
pb-4
rounded-none sm:rounded-lg;
> .dialog-header-container {
> .dialog-header-container {
@apply relative flex flex-row justify-between items-center w-full p-6 pb-0 mb-0;
@apply relative flex flex-row justify-between items-center w-full p-6 pb-0 mb-0;
...
@@ -33,7 +33,7 @@
...
@@ -33,7 +33,7 @@
}
}
> .dialog-content-container {
> .dialog-content-container {
@apply w-full h-auto flex flex-col justify-start items-start p-6 pb-0;
@apply w-full h-auto flex flex-col justify-start items-start p-6 pb-0
bg-white dark:bg-zinc-800
;
> .date-card-container {
> .date-card-container {
@apply flex flex-col justify-center items-center m-auto pb-6 select-none;
@apply flex flex-col justify-center items-center m-auto pb-6 select-none;
...
...
web/src/less/share-memo-image-dialog.less
View file @
14f9f293
.share-memo-image-dialog {
.share-memo-image-dialog {
> .dialog-container {
> .dialog-container {
@apply w-96 p-0 bg-
zinc-1
00;
@apply w-96 p-0 bg-
white dark:bg-zinc-8
00;
> .dialog-header-container {
> .dialog-header-container {
@apply py-2 pt-4 px-4 pl-6 mb-0 rounded-t-lg;
@apply py-2 pt-4 px-4 pl-6 mb-0 rounded-t-lg;
...
@@ -35,7 +35,7 @@
...
@@ -35,7 +35,7 @@
}
}
> .memo-container {
> .memo-container {
@apply w-96 max-w-full h-auto select-none relative flex flex-col justify-start items-start;
@apply w-96 max-w-full h-auto select-none relative flex flex-col justify-start items-start
bg-white dark:bg-zinc-800
;
> .memo-shortcut-img {
> .memo-shortcut-img {
@apply absolute top-0 left-0 w-full h-auto z-10;
@apply absolute top-0 left-0 w-full h-auto z-10;
...
@@ -50,7 +50,7 @@
...
@@ -50,7 +50,7 @@
}
}
> .images-container {
> .images-container {
@apply w-full h-auto flex flex-col justify-start items-start px-6 pb-2
bg-white
;
@apply w-full h-auto flex flex-col justify-start items-start px-6 pb-2;
> img {
> img {
@apply w-full h-auto mb-2 rounded;
@apply w-full h-auto mb-2 rounded;
...
@@ -58,30 +58,22 @@
...
@@ -58,30 +58,22 @@
}
}
> .watermark-container {
> .watermark-container {
@apply flex flex-row justify-between items-center w-full dark:bg-zinc-900 py-2 px-6;
@apply flex flex-row justify-between items-center w-full bg-gray-100 dark:bg-zinc-700 py-2 px-6;
> .normal-text {
@apply w-full flex flex-row justify-start items-center text-sm leading-6 text-gray-500;
> .name-text {
@apply text-black;
}
}
> .userinfo-container {
> .userinfo-container {
@apply w-64 flex flex-col justify-center items-start;
@apply w-64 flex flex-col justify-center items-start;
> .name-text {
> .name-text {
@apply text-
lg truncate font-medium text-gray-6
00;
@apply text-
sm truncate font-bold text-gray-600 dark:text-gray-3
00;
}
}
> .usage-text {
> .usage-text {
@apply
-mt-1 text-sm
text-gray-400;
@apply
text-xs
text-gray-400;
}
}
}
}
> .logo-img {
> .logo-img {
@apply h-1
2
w-auto;
@apply h-1
0
w-auto;
}
}
}
}
}
}
...
...
web/src/services/globalService.ts
View file @
14f9f293
...
@@ -11,7 +11,7 @@ const globalService = {
...
@@ -11,7 +11,7 @@ const globalService = {
initialState
:
async
()
=>
{
initialState
:
async
()
=>
{
const
defaultGlobalState
=
{
const
defaultGlobalState
=
{
locale
:
"en"
as
Locale
,
locale
:
"en"
as
Locale
,
appearance
:
"
system
"
as
Appearance
,
appearance
:
"
light
"
as
Appearance
,
systemStatus
:
{
systemStatus
:
{
allowSignUp
:
false
,
allowSignUp
:
false
,
additionalStyle
:
""
,
additionalStyle
:
""
,
...
@@ -19,10 +19,13 @@ const globalService = {
...
@@ -19,10 +19,13 @@ const globalService = {
}
as
SystemStatus
,
}
as
SystemStatus
,
};
};
const
{
locale
:
storageLocale
}
=
storage
.
get
([
"local
e"
]);
const
{
locale
:
storageLocale
,
appearance
:
storageAppearance
}
=
storage
.
get
([
"locale"
,
"appearanc
e"
]);
if
(
storageLocale
)
{
if
(
storageLocale
)
{
defaultGlobalState
.
locale
=
storageLocale
;
defaultGlobalState
.
locale
=
storageLocale
;
}
}
if
(
storageAppearance
)
{
defaultGlobalState
.
appearance
=
storageAppearance
;
}
try
{
try
{
const
{
data
}
=
(
await
api
.
getSystemStatus
()).
data
;
const
{
data
}
=
(
await
api
.
getSystemStatus
()).
data
;
...
...
web/src/services/userService.ts
View file @
14f9f293
...
@@ -3,12 +3,12 @@ import * as api from "../helpers/api";
...
@@ -3,12 +3,12 @@ import * as api from "../helpers/api";
import
*
as
storage
from
"../helpers/storage"
;
import
*
as
storage
from
"../helpers/storage"
;
import
{
UNKNOWN_ID
}
from
"../helpers/consts"
;
import
{
UNKNOWN_ID
}
from
"../helpers/consts"
;
import
store
from
"../store"
;
import
store
from
"../store"
;
import
{
setLocale
}
from
"../store/modules/global"
;
import
{
setUser
,
patchUser
,
setHost
,
setOwner
}
from
"../store/modules/user"
;
import
{
setUser
,
patchUser
,
setHost
,
setOwner
}
from
"../store/modules/user"
;
import
{
getSystemColorScheme
}
from
"../helpers/utils"
;
const
defaultSetting
:
Setting
=
{
const
defaultSetting
:
Setting
=
{
locale
:
"en"
,
locale
:
"en"
,
appearance
:
"system"
,
appearance
:
getSystemColorScheme
()
,
memoVisibility
:
"PRIVATE"
,
memoVisibility
:
"PRIVATE"
,
memoDisplayTsOption
:
"created_ts"
,
memoDisplayTsOption
:
"created_ts"
,
};
};
...
@@ -61,11 +61,15 @@ const userService = {
...
@@ -61,11 +61,15 @@ const userService = {
}
}
}
}
const
{
data
:
user
}
=
(
await
api
.
getMyselfUser
()).
data
;
const
{
data
}
=
(
await
api
.
getMyselfUser
()).
data
;
if
(
user
)
{
if
(
data
)
{
store
.
dispatch
(
setUser
(
convertResponseModelUser
(
user
)));
const
user
=
convertResponseModelUser
(
data
);
store
.
dispatch
(
setUser
(
user
));
if
(
user
.
setting
.
locale
)
{
if
(
user
.
setting
.
locale
)
{
store
.
dispatch
(
setLocale
(
user
.
setting
.
locale
));
globalService
.
setLocale
(
user
.
setting
.
locale
);
}
if
(
user
.
setting
.
appearance
)
{
globalService
.
setAppearance
(
user
.
setting
.
appearance
);
}
}
}
}
},
},
...
...
web/src/store/modules/global.ts
View file @
14f9f293
...
@@ -10,7 +10,7 @@ const globalSlice = createSlice({
...
@@ -10,7 +10,7 @@ const globalSlice = createSlice({
name
:
"global"
,
name
:
"global"
,
initialState
:
{
initialState
:
{
locale
:
"en"
,
locale
:
"en"
,
appearance
:
"
system
"
,
appearance
:
"
light
"
,
systemStatus
:
{
systemStatus
:
{
host
:
undefined
,
host
:
undefined
,
profile
:
{
profile
:
{
...
...
web/src/types/modules/setting.d.ts
View file @
14f9f293
type
Appearance
=
"light"
|
"dark"
|
"system"
;
type
Appearance
=
"light"
|
"dark"
;
interface
Setting
{
interface
Setting
{
locale
:
Locale
;
locale
:
Locale
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment