diff --git a/server/memo.go b/server/memo.go index 14b8bc52..da940b03 100644 --- a/server/memo.go +++ b/server/memo.go @@ -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 diff --git a/server/server.go b/server/server.go index bc80c3af..d99617a7 100644 --- a/server/server.go +++ b/server/server.go @@ -41,7 +41,7 @@ func NewServer(profile *profile.Profile) *Server { e.Use(middleware.StaticWithConfig(middleware.StaticConfig{ Skipper: middleware.DefaultSkipper, Root: "web/dist", - Browse: false, + Browse: true, HTML5: true, })) diff --git a/server/user.go b/server/user.go index 629158de..f19bb6f5 100644 --- a/server/user.go +++ b/server/user.go @@ -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.Name)); err != nil { + if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(username)); err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to encode user response").SetInternal(err) } return nil diff --git a/store/memo.go b/store/memo.go index 5b40782e..1019daa9 100644 --- a/store/memo.go +++ b/store/memo.go @@ -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( diff --git a/web/public/icons/visibility.svg b/web/public/icons/visibility.svg new file mode 100644 index 00000000..35bdde85 --- /dev/null +++ b/web/public/icons/visibility.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/src/components/Memo.tsx b/web/src/components/Memo.tsx index 806e3aa9..40579052 100644 --- a/web/src/components/Memo.tsx +++ b/web/src/components/Memo.tsx @@ -161,6 +161,9 @@ const Memo: React.FC = (props: Props) => { PINNED + + PUBLIC +
diff --git a/web/src/components/MemoCardDialog.tsx b/web/src/components/MemoCardDialog.tsx index 3ec66932..999d710c 100644 --- a/web/src/components/MemoCardDialog.tsx +++ b/web/src/components/MemoCardDialog.tsx @@ -104,12 +104,27 @@ const MemoCardDialog: React.FC = (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 ( <>

{utils.getDateTimeString(memo.createdTs)}

+ diff --git a/web/src/components/MenuBtnsPopup.tsx b/web/src/components/MenuBtnsPopup.tsx index b418a48e..410986fb 100644 --- a/web/src/components/MenuBtnsPopup.tsx +++ b/web/src/components/MenuBtnsPopup.tsx @@ -1,6 +1,7 @@ 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) => { const { shownStatus, setShownStatus } = props; + const user = useAppSelector((state) => state.user.user); const popupElRef = useRef(null); useEffect(() => { @@ -55,10 +57,6 @@ const MenuBtnsPopup: React.FC = (props: Props) => { window.location.reload(); }; - const handleSignInBtnClick = async () => { - locationService.replaceHistory("/signin"); - }; - return (
- + {!userService.isVisitorMode() ? ( + + ) : user ? ( + + ) : ( + + )}
); }; diff --git a/web/src/components/UserBanner.tsx b/web/src/components/UserBanner.tsx index 2a607bb7..7b93dcd2 100644 --- a/web/src/components/UserBanner.tsx +++ b/web/src/components/UserBanner.tsx @@ -22,7 +22,9 @@ const UserBanner: React.FC = () => { .getUserNameById(currentUserId) .then(({ data }) => { const { data: username } = data; - setUsername(username); + if (username) { + setUsername(username); + } }) .catch(() => { toastHelper.error("User not found"); diff --git a/web/src/pages/Home.tsx b/web/src/pages/Home.tsx index 474c2f53..b6c304ad 100644 --- a/web/src/pages/Home.tsx +++ b/web/src/pages/Home.tsx @@ -1,5 +1,6 @@ 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,10 +18,20 @@ function Home() { userService .doSignIn() .catch() - .finally(() => { - if (!userService.isVisitorMode() && !userService.getState().user) { - locationService.replaceHistory("/signin"); - return; + .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(); }); diff --git a/web/src/types/modules/memo.d.ts b/web/src/types/modules/memo.d.ts index 058eceac..6b4e1e8c 100644 --- a/web/src/types/modules/memo.d.ts +++ b/web/src/types/modules/memo.d.ts @@ -1,5 +1,7 @@ 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; }