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
1afc1834
Commit
1afc1834
authored
Jul 08, 2022
by
boojack
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: update memo visibility in frontend
parent
697d01e3
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
72 additions
and
19 deletions
+72
-19
memo.go
server/memo.go
+7
-0
server.go
server/server.go
+1
-1
user.go
server/user.go
+5
-3
memo.go
store/memo.go
+1
-3
visibility.svg
web/public/icons/visibility.svg
+1
-0
Memo.tsx
web/src/components/Memo.tsx
+3
-0
MemoCardDialog.tsx
web/src/components/MemoCardDialog.tsx
+15
-0
MenuBtnsPopup.tsx
web/src/components/MenuBtnsPopup.tsx
+15
-7
UserBanner.tsx
web/src/components/UserBanner.tsx
+3
-1
Home.tsx
web/src/pages/Home.tsx
+16
-4
memo.d.ts
web/src/types/modules/memo.d.ts
+5
-0
No files found.
server/memo.go
View file @
1afc1834
...
...
@@ -76,6 +76,13 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
memoFind
.
CreatorID
=
&
userID
}
// Only can get PUBLIC memos in visitor mode
_
,
ok
:=
c
.
Get
(
getUserIDContextKey
())
.
(
int
)
if
!
ok
{
publicVisibility
:=
api
.
Public
memoFind
.
Visibility
=
&
publicVisibility
}
rowStatus
:=
api
.
RowStatus
(
c
.
QueryParam
(
"rowStatus"
))
if
rowStatus
!=
""
{
memoFind
.
RowStatus
=
&
rowStatus
...
...
server/server.go
View file @
1afc1834
...
...
@@ -41,7 +41,7 @@ func NewServer(profile *profile.Profile) *Server {
e
.
Use
(
middleware
.
StaticWithConfig
(
middleware
.
StaticConfig
{
Skipper
:
middleware
.
DefaultSkipper
,
Root
:
"web/dist"
,
Browse
:
fals
e
,
Browse
:
tru
e
,
HTML5
:
true
,
}))
...
...
server/user.go
View file @
1afc1834
...
...
@@ -63,12 +63,14 @@ func (s *Server) registerUserRoutes(g *echo.Group) {
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to fetch user"
)
.
SetInternal
(
err
)
}
if
user
==
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusNotFound
,
"User not found"
)
username
:=
""
if
user
!=
nil
{
username
=
user
.
Name
}
c
.
Response
()
.
Header
()
.
Set
(
echo
.
HeaderContentType
,
echo
.
MIMEApplicationJSONCharsetUTF8
)
if
err
:=
json
.
NewEncoder
(
c
.
Response
()
.
Writer
)
.
Encode
(
composeResponse
(
user
.
N
ame
));
err
!=
nil
{
if
err
:=
json
.
NewEncoder
(
c
.
Response
()
.
Writer
)
.
Encode
(
composeResponse
(
user
n
ame
));
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to encode user response"
)
.
SetInternal
(
err
)
}
return
nil
...
...
store/memo.go
View file @
1afc1834
...
...
@@ -183,9 +183,7 @@ func patchMemoRaw(db *sql.DB, patch *api.MemoPatch) (*memoRaw, error) {
}
defer
row
.
Close
()
if
!
row
.
Next
()
{
return
nil
,
&
common
.
Error
{
Code
:
common
.
NotFound
,
Err
:
fmt
.
Errorf
(
"not found"
)}
}
row
.
Next
()
var
memoRaw
memoRaw
if
err
:=
row
.
Scan
(
...
...
web/public/icons/visibility.svg
0 → 100644
View file @
1afc1834
<svg
xmlns=
"http://www.w3.org/2000/svg"
height=
"48"
width=
"48"
><path
d=
"M24 31.5q3.55 0 6.025-2.475Q32.5 26.55 32.5 23q0-3.55-2.475-6.025Q27.55 14.5 24 14.5q-3.55 0-6.025 2.475Q15.5 19.45 15.5 23q0 3.55 2.475 6.025Q20.45 31.5 24 31.5Zm0-2.9q-2.35 0-3.975-1.625T18.4 23q0-2.35 1.625-3.975T24 17.4q2.35 0 3.975 1.625T29.6 23q0 2.35-1.625 3.975T24 28.6Zm0 9.4q-7.3 0-13.2-4.15Q4.9 29.7 2 23q2.9-6.7 8.8-10.85Q16.7 8 24 8q7.3 0 13.2 4.15Q43.1 16.3 46 23q-2.9 6.7-8.8 10.85Q31.3 38 24 38Zm0-15Zm0 12q6.05 0 11.125-3.275T42.85 23q-2.65-5.45-7.725-8.725Q30.05 11 24 11t-11.125 3.275Q7.8 17.55 5.1 23q2.7 5.45 7.775 8.725Q17.95 35 24 35Z"
/></svg>
\ No newline at end of file
web/src/components/Memo.tsx
View file @
1afc1834
...
...
@@ -161,6 +161,9 @@ const Memo: React.FC<Props> = (props: Props) => {
<
Only
when=
{
memo
.
pinned
}
>
<
span
className=
"ml-2"
>
PINNED
</
span
>
</
Only
>
<
Only
when=
{
memo
.
visibility
===
"PUBLIC"
}
>
<
span
className=
"ml-2"
>
PUBLIC
</
span
>
</
Only
>
</
span
>
<
div
className=
{
`btns-container ${userService.isVisitorMode() ? "!hidden" : ""}`
}
>
<
span
className=
"btn more-action-btn"
>
...
...
web/src/components/MemoCardDialog.tsx
View file @
1afc1834
...
...
@@ -104,12 +104,27 @@ const MemoCardDialog: React.FC<Props> = (props: Props) => {
editorStateService
.
setEditMemoWithId
(
memo
.
id
);
},
[
memo
.
id
]);
const
handleVisibilityClick
=
async
()
=>
{
const
visibility
=
memo
.
visibility
===
"PRIVATE"
?
"PUBLIC"
:
"PRIVATE"
;
await
memoService
.
patchMemo
({
id
:
memo
.
id
,
visibility
:
visibility
,
});
setMemo
({
...
memo
,
visibility
:
visibility
,
});
};
return
(
<>
<
div
className=
"memo-card-container"
>
<
div
className=
"header-container"
>
<
p
className=
"time-text"
>
{
utils
.
getDateTimeString
(
memo
.
createdTs
)
}
</
p
>
<
div
className=
"btns-container"
>
<
button
className=
"btn edit-btn"
onClick=
{
handleVisibilityClick
}
>
<
img
className=
{
`icon-img ${memo.visibility === "PRIVATE" ? "opacity-30" : ""}`
}
src=
"/icons/visibility.svg"
/>
</
button
>
<
button
className=
"btn edit-btn"
onClick=
{
handleEditMemoBtnClick
}
>
<
img
className=
"icon-img"
src=
"/icons/edit.svg"
/>
</
button
>
...
...
web/src/components/MenuBtnsPopup.tsx
View file @
1afc1834
import
{
useEffect
,
useRef
}
from
"react"
;
import
*
as
api
from
"../helpers/api"
;
import
{
locationService
,
userService
}
from
"../services"
;
import
{
useAppSelector
}
from
"../store"
;
import
toastHelper
from
"./Toast"
;
import
showAboutSiteDialog
from
"./AboutSiteDialog"
;
import
"../less/menu-btns-popup.less"
;
...
...
@@ -12,6 +13,7 @@ interface Props {
const
MenuBtnsPopup
:
React
.
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
{
shownStatus
,
setShownStatus
}
=
props
;
const
user
=
useAppSelector
((
state
)
=>
state
.
user
.
user
);
const
popupElRef
=
useRef
<
HTMLDivElement
>
(
null
);
useEffect
(()
=>
{
...
...
@@ -55,10 +57,6 @@ const MenuBtnsPopup: React.FC<Props> = (props: Props) => {
window
.
location
.
reload
();
};
const
handleSignInBtnClick
=
async
()
=>
{
locationService
.
replaceHistory
(
"/signin"
);
};
return
(
<
div
className=
{
`menu-btns-popup ${shownStatus ? "" : "hidden"}`
}
ref=
{
popupElRef
}
>
<
button
className=
"btn action-btn"
onClick=
{
handleAboutBtnClick
}
>
...
...
@@ -67,9 +65,19 @@ const MenuBtnsPopup: React.FC<Props> = (props: Props) => {
<
button
className=
"btn action-btn"
onClick=
{
handlePingBtnClick
}
>
<
span
className=
"icon"
>
🎯
</
span
>
Ping
</
button
>
<
button
className=
"btn action-btn"
onClick=
{
!
userService
.
isVisitorMode
()
?
handleSignOutBtnClick
:
handleSignInBtnClick
}
>
<
span
className=
"icon"
>
👋
</
span
>
{
!
userService
.
isVisitorMode
()
?
"Sign out"
:
"Sign in"
}
{
!
userService
.
isVisitorMode
()
?
(
<
button
className=
"btn action-btn"
onClick=
{
handleSignOutBtnClick
}
>
<
span
className=
"icon"
>
👋
</
span
>
Sign out
</
button
>
)
:
user
?
(
<
button
className=
"btn action-btn"
onClick=
{
()
=>
(
window
.
location
.
href
=
"/"
)
}
>
<
span
className=
"icon"
>
🏠
</
span
>
Go Back
</
button
>
)
:
(
<
button
className=
"btn action-btn"
onClick=
{
()
=>
(
window
.
location
.
href
=
"/signin"
)
}
>
<
span
className=
"icon"
>
👉
</
span
>
Sign in
</
button
>
)
}
</
div
>
);
};
...
...
web/src/components/UserBanner.tsx
View file @
1afc1834
...
...
@@ -22,7 +22,9 @@ const UserBanner: React.FC<Props> = () => {
.
getUserNameById
(
currentUserId
)
.
then
(({
data
})
=>
{
const
{
data
:
username
}
=
data
;
if
(
username
)
{
setUsername
(
username
);
}
})
.
catch
(()
=>
{
toastHelper
.
error
(
"User not found"
);
...
...
web/src/pages/Home.tsx
View file @
1afc1834
import
{
useEffect
}
from
"react"
;
import
{
locationService
,
userService
}
from
"../services"
;
import
*
as
api
from
"../helpers/api"
;
import
useLoading
from
"../hooks/useLoading"
;
import
Only
from
"../components/common/OnlyWhen"
;
import
Sidebar
from
"../components/Sidebar"
;
...
...
@@ -7,6 +8,7 @@ import MemosHeader from "../components/MemosHeader";
import
MemoEditor
from
"../components/MemoEditor"
;
import
MemoFilter
from
"../components/MemoFilter"
;
import
MemoList
from
"../components/MemoList"
;
import
toastHelper
from
"../components/Toast"
;
import
"../less/home.less"
;
function
Home
()
{
...
...
@@ -16,11 +18,21 @@ function Home() {
userService
.
doSignIn
()
.
catch
()
.
finally
(()
=>
{
if
(
!
userService
.
isVisitorMode
()
&&
!
userService
.
getState
().
user
)
{
.
finally
(
async
()
=>
{
if
(
!
userService
.
getState
().
user
)
{
if
(
userService
.
isVisitorMode
())
{
const
currentUserId
=
userService
.
getUserIdFromPath
()
as
number
;
const
{
data
:
{
data
:
username
},
}
=
await
api
.
getUserNameById
(
currentUserId
);
if
(
!
username
)
{
toastHelper
.
error
(
"User not found"
);
}
}
else
{
locationService
.
replaceHistory
(
"/signin"
);
return
;
}
}
loadingState
.
setFinish
();
});
},
[]);
...
...
web/src/types/modules/memo.d.ts
View file @
1afc1834
type
MemoId
=
number
;
type
Visibility
=
"PUBLIC"
|
"PRIVATE"
;
interface
Memo
{
id
:
MemoId
;
...
...
@@ -9,6 +11,7 @@ interface Memo {
rowStatus
:
RowStatus
;
content
:
string
;
visibility
:
Visibility
;
pinned
:
boolean
;
}
...
...
@@ -21,9 +24,11 @@ interface MemoPatch {
id
:
MemoId
;
content
?:
string
;
rowStatus
?:
RowStatus
;
visibility
?:
Visibility
;
}
interface
MemoFind
{
creatorId
?:
UserId
;
rowStatus
?:
RowStatus
;
visibility
?:
Visibility
;
}
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