chore: update memo service (#1138)

* chore: update memo service

* chore: update
This commit is contained in:
boojack 2023-02-22 20:07:55 +08:00 committed by GitHub
parent 42d849abfc
commit 29124f56bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 59 additions and 133 deletions

View file

@ -1,5 +1,8 @@
package api package api
// MaxContentLength means the max memo content bytes is 1MB.
const MaxContentLength = 1 << 30
// Visibility is the type of a visibility. // Visibility is the type of a visibility.
type Visibility string type Visibility string
@ -37,7 +40,6 @@ type Memo struct {
Content string `json:"content"` Content string `json:"content"`
Visibility Visibility `json:"visibility"` Visibility Visibility `json:"visibility"`
Pinned bool `json:"pinned"` Pinned bool `json:"pinned"`
DisplayTs int64 `json:"displayTs"`
// Related fields // Related fields
Creator *User `json:"creator"` Creator *User `json:"creator"`
@ -86,8 +88,8 @@ type MemoFind struct {
VisibilityList []Visibility VisibilityList []Visibility
// Pagination // Pagination
Limit int Limit *int
Offset int Offset *int
} }
type MemoDelete struct { type MemoDelete struct {

View file

@ -16,8 +16,6 @@ const (
UserSettingAppearanceKey UserSettingKey = "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 UserSettingKey = "memoDisplayTsOption"
) )
// String returns the string format of UserSettingKey type. // String returns the string format of UserSettingKey type.
@ -29,17 +27,14 @@ func (key UserSettingKey) String() string {
return "appearance" return "appearance"
case UserSettingMemoVisibilityKey: case UserSettingMemoVisibilityKey:
return "memoVisibility" return "memoVisibility"
case UserSettingMemoDisplayTsOptionKey:
return "memoDisplayTsOption"
} }
return "" return ""
} }
var ( var (
UserSettingLocaleValue = []string{"en", "zh", "vi", "fr", "nl", "sv", "de", "es", "uk", "ru", "it", "hant", "ko"} UserSettingLocaleValue = []string{"en", "zh", "vi", "fr", "nl", "sv", "de", "es", "uk", "ru", "it", "hant", "ko"}
UserSettingAppearanceValue = []string{"system", "light", "dark"} UserSettingAppearanceValue = []string{"system", "light", "dark"}
UserSettingMemoVisibilityValue = []Visibility{Private, Protected, Public} UserSettingMemoVisibilityValue = []Visibility{Private, Protected, Public}
UserSettingMemoDisplayTsOptionKeyValue = []string{"created_ts", "updated_ts"}
) )
type UserSetting struct { type UserSetting struct {
@ -83,15 +78,6 @@ func (upsert UserSettingUpsert) Validate() error {
if !slices.Contains(UserSettingMemoVisibilityValue, memoVisibilityValue) { if !slices.Contains(UserSettingMemoVisibilityValue, memoVisibilityValue) {
return fmt.Errorf("invalid user setting memo visibility value") return fmt.Errorf("invalid user setting memo visibility value")
} }
} else if upsert.Key == UserSettingMemoDisplayTsOptionKey {
memoDisplayTsOption := "created_ts"
err := json.Unmarshal([]byte(upsert.Value), &memoDisplayTsOption)
if err != nil {
return fmt.Errorf("failed to unmarshal user setting memo display ts option")
}
if !slices.Contains(UserSettingMemoDisplayTsOptionKeyValue, memoDisplayTsOption) {
return fmt.Errorf("invalid user setting memo display ts option value")
}
} else { } else {
return fmt.Errorf("invalid user setting key") return fmt.Errorf("invalid user setting key")
} }

View file

@ -4,7 +4,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"sort"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -71,6 +70,10 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
} }
} }
if len(memoCreate.Content) > api.MaxContentLength {
return echo.NewHTTPError(http.StatusBadRequest, "Content size overflow, up to 1MB").SetInternal(err)
}
memoCreate.CreatorID = userID memoCreate.CreatorID = userID
memo, err := s.Store.CreateMemo(ctx, memoCreate) memo, err := s.Store.CreateMemo(ctx, memoCreate)
if err != nil { if err != nil {
@ -127,6 +130,10 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted patch memo request").SetInternal(err) return echo.NewHTTPError(http.StatusBadRequest, "Malformatted patch memo request").SetInternal(err)
} }
if memoPatch.Content != nil && len(*memoPatch.Content) > api.MaxContentLength {
return echo.NewHTTPError(http.StatusBadRequest, "Content size overflow, up to 1MB").SetInternal(err)
}
memo, err = s.Store.PatchMemo(ctx, memoPatch) memo, err = s.Store.PatchMemo(ctx, memoPatch)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to patch memo").SetInternal(err) return echo.NewHTTPError(http.StatusInternalServerError, "Failed to patch memo").SetInternal(err)
@ -192,10 +199,10 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
memoFind.VisibilityList = visibilityList memoFind.VisibilityList = visibilityList
} }
if limit, err := strconv.Atoi(c.QueryParam("limit")); err == nil { if limit, err := strconv.Atoi(c.QueryParam("limit")); err == nil {
memoFind.Limit = limit memoFind.Limit = &limit
} }
if offset, err := strconv.Atoi(c.QueryParam("offset")); err == nil { if offset, err := strconv.Atoi(c.QueryParam("offset")); err == nil {
memoFind.Offset = offset memoFind.Offset = &offset
} }
list, err := s.Store.FindMemoList(ctx, memoFind) list, err := s.Store.FindMemoList(ctx, memoFind)
@ -214,20 +221,9 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
} }
} }
sort.Slice(pinnedMemoList, func(i, j int) bool {
return pinnedMemoList[i].DisplayTs > pinnedMemoList[j].DisplayTs
})
sort.Slice(unpinnedMemoList, func(i, j int) bool {
return unpinnedMemoList[i].DisplayTs > unpinnedMemoList[j].DisplayTs
})
memoList := []*api.Memo{} memoList := []*api.Memo{}
memoList = append(memoList, pinnedMemoList...) memoList = append(memoList, pinnedMemoList...)
memoList = append(memoList, unpinnedMemoList...) memoList = append(memoList, unpinnedMemoList...)
if memoFind.Limit != 0 {
memoList = memoList[memoFind.Offset:common.Min(len(memoList), memoFind.Offset+memoFind.Limit)]
}
return c.JSON(http.StatusOK, composeResponse(memoList)) return c.JSON(http.StatusOK, composeResponse(memoList))
}) })
@ -399,11 +395,11 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to fetch memo list").SetInternal(err) return echo.NewHTTPError(http.StatusInternalServerError, "Failed to fetch memo list").SetInternal(err)
} }
displayTsList := []int64{} createdTsList := []int64{}
for _, memo := range list { for _, memo := range list {
displayTsList = append(displayTsList, memo.DisplayTs) createdTsList = append(createdTsList, memo.CreatedTs)
} }
return c.JSON(http.StatusOK, composeResponse(displayTsList)) return c.JSON(http.StatusOK, composeResponse(createdTsList))
}) })
g.GET("/memo/all", func(c echo.Context) error { g.GET("/memo/all", func(c echo.Context) error {
@ -436,10 +432,10 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
memoFind.VisibilityList = visibilityList memoFind.VisibilityList = visibilityList
} }
if limit, err := strconv.Atoi(c.QueryParam("limit")); err == nil { if limit, err := strconv.Atoi(c.QueryParam("limit")); err == nil {
memoFind.Limit = limit memoFind.Limit = &limit
} }
if offset, err := strconv.Atoi(c.QueryParam("offset")); err == nil { if offset, err := strconv.Atoi(c.QueryParam("offset")); err == nil {
memoFind.Offset = offset memoFind.Offset = &offset
} }
// Only fetch normal status memos. // Only fetch normal status memos.
@ -450,14 +446,6 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to fetch all memo list").SetInternal(err) return echo.NewHTTPError(http.StatusInternalServerError, "Failed to fetch all memo list").SetInternal(err)
} }
sort.Slice(list, func(i, j int) bool {
return list[i].DisplayTs > list[j].DisplayTs
})
if memoFind.Limit != 0 {
list = list[memoFind.Offset:common.Min(len(list), memoFind.Offset+memoFind.Limit)]
}
return c.JSON(http.StatusOK, composeResponse(list)) return c.JSON(http.StatusOK, composeResponse(list))
}) })

View file

@ -3,7 +3,6 @@ package store
import ( import (
"context" "context"
"database/sql" "database/sql"
"encoding/json"
"fmt" "fmt"
"strings" "strings"
@ -43,7 +42,6 @@ func (raw *memoRaw) toMemo() *api.Memo {
// Domain specific fields // Domain specific fields
Content: raw.Content, Content: raw.Content,
Visibility: raw.Visibility, Visibility: raw.Visibility,
DisplayTs: raw.CreatedTs,
Pinned: raw.Pinned, Pinned: raw.Pinned,
} }
} }
@ -56,25 +54,6 @@ func (s *Store) ComposeMemo(ctx context.Context, memo *api.Memo) (*api.Memo, err
return nil, err return nil, err
} }
memoDisplayTsOptionKey := api.UserSettingMemoDisplayTsOptionKey
memoDisplayTsOptionSetting, err := s.FindUserSetting(ctx, &api.UserSettingFind{
UserID: memo.CreatorID,
Key: &memoDisplayTsOptionKey,
})
if err != nil {
return nil, err
}
memoDisplayTsOptionValue := "created_ts"
if memoDisplayTsOptionSetting != nil {
err = json.Unmarshal([]byte(memoDisplayTsOptionSetting.Value), &memoDisplayTsOptionValue)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal user setting memo display ts option value")
}
}
if memoDisplayTsOptionValue == "updated_ts" {
memo.DisplayTs = memo.UpdatedTs
}
return memo, nil return memo, nil
} }
@ -329,6 +308,13 @@ func findMemoRawList(ctx context.Context, tx *sql.Tx, find *api.MemoFind) ([]*me
WHERE ` + strings.Join(where, " AND ") + ` WHERE ` + strings.Join(where, " AND ") + `
ORDER BY memo.created_ts DESC ORDER BY memo.created_ts DESC
` `
if find.Limit != nil {
query = fmt.Sprintf("%s LIMIT %d", query, *find.Limit)
if find.Offset != nil {
query = fmt.Sprintf("%s OFFSET %d", query, *find.Offset)
}
}
rows, err := tx.QueryContext(ctx, query, args...) rows, err := tx.QueryContext(ctx, query, args...)
if err != nil { if err != nil {
return nil, FormatError(err) return nil, FormatError(err)

View file

@ -9,7 +9,7 @@ interface Props {
const DailyMemo: React.FC<Props> = (props: Props) => { const DailyMemo: React.FC<Props> = (props: Props) => {
const { memo } = props; const { memo } = props;
const displayTimeStr = utils.getTimeString(memo.displayTs); const createdTimeStr = utils.getTimeString(memo.createdTs);
const displayConfig: DisplayConfig = { const displayConfig: DisplayConfig = {
enableExpand: false, enableExpand: false,
}; };
@ -17,7 +17,7 @@ const DailyMemo: React.FC<Props> = (props: Props) => {
return ( return (
<div className="daily-memo-wrapper"> <div className="daily-memo-wrapper">
<div className="time-wrapper"> <div className="time-wrapper">
<span className="normal-text">{displayTimeStr}</span> <span className="normal-text">{createdTimeStr}</span>
</div> </div>
<div className="memo-container"> <div className="memo-container">
<MemoContent content={memo.content} displayConfig={displayConfig} /> <MemoContent content={memo.content} displayConfig={displayConfig} />

View file

@ -31,10 +31,10 @@ const DailyReviewDialog: React.FC<Props> = (props: Props) => {
.filter( .filter(
(m) => (m) =>
m.rowStatus === "NORMAL" && m.rowStatus === "NORMAL" &&
utils.getTimeStampByDate(m.displayTs) >= currentDateStamp && utils.getTimeStampByDate(m.createdTs) >= currentDateStamp &&
utils.getTimeStampByDate(m.displayTs) < currentDateStamp + DAILY_TIMESTAMP utils.getTimeStampByDate(m.createdTs) < currentDateStamp + DAILY_TIMESTAMP
) )
.sort((a, b) => utils.getTimeStampByDate(a.displayTs) - utils.getTimeStampByDate(b.displayTs)); .sort((a, b) => utils.getTimeStampByDate(a.createdTs) - utils.getTimeStampByDate(b.createdTs));
const handleShareBtnClick = () => { const handleShareBtnClick = () => {
if (!memosElRef.current) { if (!memosElRef.current) {

View file

@ -1,3 +1,4 @@
import { Tooltip } from "@mui/joy";
import copy from "copy-to-clipboard"; import copy from "copy-to-clipboard";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { memo, useEffect, useRef, useState } from "react"; import { memo, useEffect, useRef, useState } from "react";
@ -34,15 +35,16 @@ const Memo: React.FC<Props> = (props: Props) => {
const locationStore = useLocationStore(); const locationStore = useLocationStore();
const userStore = useUserStore(); const userStore = useUserStore();
const memoStore = useMemoStore(); const memoStore = useMemoStore();
const [displayTimeStr, setDisplayTimeStr] = useState<string>(getFormatedMemoTimeStr(memo.displayTs, i18n.language)); const [createdTimeStr, setCreatedTimeStr] = useState<string>(getFormatedMemoTimeStr(memo.createdTs, i18n.language));
const memoContainerRef = useRef<HTMLDivElement>(null); const memoContainerRef = useRef<HTMLDivElement>(null);
const isVisitorMode = userStore.isVisitorMode(); const isVisitorMode = userStore.isVisitorMode();
const updatedTimeStr = getFormatedMemoTimeStr(memo.updatedTs, i18n.language);
useEffect(() => { useEffect(() => {
let intervalFlag: any = -1; let intervalFlag: any = -1;
if (Date.now() - memo.displayTs < 1000 * 60 * 60 * 24) { if (Date.now() - memo.createdTs < 1000 * 60 * 60 * 24) {
intervalFlag = setInterval(() => { intervalFlag = setInterval(() => {
setDisplayTimeStr(getFormatedMemoTimeStr(memo.displayTs, i18n.language)); setCreatedTimeStr(getFormatedMemoTimeStr(memo.createdTs, i18n.language));
}, 1000 * 1); }, 1000 * 1);
} }
@ -166,7 +168,7 @@ const Memo: React.FC<Props> = (props: Props) => {
editorStore.setEditMemoWithId(memo.id); editorStore.setEditMemoWithId(memo.id);
}; };
const handleMemoDisplayTimeClick = () => { const handleMemoCreatedTimeClick = () => {
showChangeMemoCreatedTsDialog(memo.id); showChangeMemoCreatedTsDialog(memo.id);
}; };
@ -184,9 +186,11 @@ const Memo: React.FC<Props> = (props: Props) => {
{memo.pinned && <div className="corner-container"></div>} {memo.pinned && <div className="corner-container"></div>}
<div className="memo-top-wrapper"> <div className="memo-top-wrapper">
<div className="status-text-container"> <div className="status-text-container">
<span className="time-text" onDoubleClick={handleMemoDisplayTimeClick}> <Tooltip title={`Updated at ${updatedTimeStr}`} placement="top" arrow>
{displayTimeStr} <span className="time-text" onDoubleClick={handleMemoCreatedTimeClick}>
</span> {createdTimeStr}
</span>
</Tooltip>
{memo.visibility !== "PRIVATE" && !isVisitorMode && ( {memo.visibility !== "PRIVATE" && !isVisitorMode && (
<span <span
className={`status-text ${memo.visibility.toLocaleLowerCase()}`} className={`status-text ${memo.visibility.toLocaleLowerCase()}`}

View file

@ -1,6 +1,6 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useLocationStore, useMemoStore, useShortcutStore, useUserStore } from "../store/module"; import { useLocationStore, useMemoStore, useShortcutStore } from "../store/module";
import { TAG_REG, LINK_REG } from "../labs/marked/parser"; import { TAG_REG, LINK_REG } from "../labs/marked/parser";
import * as utils from "../helpers/utils"; import * as utils from "../helpers/utils";
import { DEFAULT_MEMO_LIMIT } from "../helpers/consts"; import { DEFAULT_MEMO_LIMIT } from "../helpers/consts";
@ -11,12 +11,10 @@ import "../less/memo-list.less";
const MemoList = () => { const MemoList = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const userStore = useUserStore();
const memoStore = useMemoStore(); const memoStore = useMemoStore();
const shortcutStore = useShortcutStore(); const shortcutStore = useShortcutStore();
const locationStore = useLocationStore(); const locationStore = useLocationStore();
const query = locationStore.state.query; const query = locationStore.state.query;
const memoDisplayTsOption = userStore.state.user?.setting.memoDisplayTsOption;
const { memos, isFetching } = memoStore.state; const { memos, isFetching } = memoStore.state;
const [isComplete, setIsComplete] = useState<boolean>(false); const [isComplete, setIsComplete] = useState<boolean>(false);
@ -54,7 +52,7 @@ const MemoList = () => {
if ( if (
duration && duration &&
duration.from < duration.to && duration.from < duration.to &&
(utils.getTimeStampByDate(memo.displayTs) < duration.from || utils.getTimeStampByDate(memo.displayTs) > duration.to) (utils.getTimeStampByDate(memo.createdTs) < duration.from || utils.getTimeStampByDate(memo.createdTs) > duration.to)
) { ) {
shouldShow = false; shouldShow = false;
} }
@ -79,7 +77,7 @@ const MemoList = () => {
const pinnedMemos = shownMemos.filter((m) => m.pinned); const pinnedMemos = shownMemos.filter((m) => m.pinned);
const unpinnedMemos = shownMemos.filter((m) => !m.pinned); const unpinnedMemos = shownMemos.filter((m) => !m.pinned);
const memoSort = (mi: Memo, mj: Memo) => { const memoSort = (mi: Memo, mj: Memo) => {
return mj.displayTs - mi.displayTs; return mj.createdTs - mi.createdTs;
}; };
pinnedMemos.sort(memoSort); pinnedMemos.sort(memoSort);
unpinnedMemos.sort(memoSort); unpinnedMemos.sort(memoSort);
@ -99,7 +97,7 @@ const MemoList = () => {
console.error(error); console.error(error);
toastHelper.error(error.response.data.message); toastHelper.error(error.response.data.message);
}); });
}, [memoDisplayTsOption]); }, []);
useEffect(() => { useEffect(() => {
const pageWrapper = document.body.querySelector(".page-wrapper"); const pageWrapper = document.body.querySelector(".page-wrapper");
@ -134,7 +132,7 @@ const MemoList = () => {
return ( return (
<div className="memo-list-container"> <div className="memo-list-container">
{sortedMemos.map((memo) => ( {sortedMemos.map((memo) => (
<Memo key={`${memo.id}-${memo.displayTs}`} memo={memo} /> <Memo key={`${memo.id}-${memo.createdTs}`} memo={memo} />
))} ))}
{isFetching ? ( {isFetching ? (
<div className="status-text-container fetching-tip"> <div className="status-text-container fetching-tip">

View file

@ -2,7 +2,7 @@ import { Select, Switch, Option } from "@mui/joy";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useGlobalStore, useUserStore } from "../../store/module"; import { useGlobalStore, useUserStore } from "../../store/module";
import { VISIBILITY_SELECTOR_ITEMS, MEMO_DISPLAY_TS_OPTION_SELECTOR_ITEMS } from "../../helpers/consts"; import { VISIBILITY_SELECTOR_ITEMS } from "../../helpers/consts";
import AppearanceSelect from "../AppearanceSelect"; import AppearanceSelect from "../AppearanceSelect";
import LocaleSelect from "../LocaleSelect"; import LocaleSelect from "../LocaleSelect";
import "../../less/settings/preferences-section.less"; import "../../less/settings/preferences-section.less";
@ -20,13 +20,6 @@ const PreferencesSection = () => {
}; };
}); });
const memoDisplayTsOptionSelectorItems = MEMO_DISPLAY_TS_OPTION_SELECTOR_ITEMS.map((item) => {
return {
value: item.value,
text: t(`setting.preference-section.${item.value}`),
};
});
const handleLocaleSelectChange = async (locale: Locale) => { const handleLocaleSelectChange = async (locale: Locale) => {
await userStore.upsertUserSetting("locale", locale); await userStore.upsertUserSetting("locale", locale);
globalStore.setLocale(locale); globalStore.setLocale(locale);
@ -41,10 +34,6 @@ const PreferencesSection = () => {
await userStore.upsertUserSetting("memoVisibility", value); await userStore.upsertUserSetting("memoVisibility", value);
}; };
const handleMemoDisplayTsOptionChanged = async (value: string) => {
await userStore.upsertUserSetting("memoDisplayTsOption", value);
};
const handleIsFoldingEnabledChanged = (event: React.ChangeEvent<HTMLInputElement>) => { const handleIsFoldingEnabledChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
userStore.upsertLocalSetting({ ...localSetting, enableFoldMemo: event.target.checked }); userStore.upsertLocalSetting({ ...localSetting, enableFoldMemo: event.target.checked });
}; };
@ -83,24 +72,6 @@ const PreferencesSection = () => {
))} ))}
</Select> </Select>
</div> </div>
<label className="form-label selector">
<span className="normal-text">{t("setting.preference-section.default-memo-sort-option")}</span>
<Select
className="!min-w-[10rem] w-auto text-sm"
value={setting.memoDisplayTsOption}
onChange={(_, value) => {
if (value) {
handleMemoDisplayTsOptionChanged(value);
}
}}
>
{memoDisplayTsOptionSelectorItems.map((item) => (
<Option key={item.value} value={item.value} className="whitespace-nowrap">
{item.text}
</Option>
))}
</Select>
</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>
<Switch className="ml-2" checked={localSetting.enableFoldMemo} onChange={handleIsFoldingEnabledChanged} /> <Switch className="ml-2" checked={localSetting.enableFoldMemo} onChange={handleIsFoldingEnabledChanged} />

View file

@ -44,7 +44,7 @@ const ShareMemoDialog: React.FC<Props> = (props: Props) => {
const memoElRef = useRef<HTMLDivElement>(null); const memoElRef = useRef<HTMLDivElement>(null);
const memo = { const memo = {
...propsMemo, ...propsMemo,
createdAtStr: utils.getDateTimeString(propsMemo.displayTs), createdAtStr: utils.getDateTimeString(propsMemo.createdTs),
}; };
const createdDays = Math.ceil((Date.now() - utils.getTimeStampByDate(user.createdTs)) / 1000 / 3600 / 24); const createdDays = Math.ceil((Date.now() - utils.getTimeStampByDate(user.createdTs)) / 1000 / 3600 / 24);

View file

@ -13,11 +13,6 @@ export const VISIBILITY_SELECTOR_ITEMS = [
{ text: "PUBLIC", value: "PUBLIC" }, { text: "PUBLIC", value: "PUBLIC" },
]; ];
export const MEMO_DISPLAY_TS_OPTION_SELECTOR_ITEMS = [
{ text: "created_ts", value: "created_ts" },
{ text: "updated_ts", value: "updated_ts" },
];
// space width for tab action in editor // space width for tab action in editor
export const TAB_SPACE_WIDTH = 2; export const TAB_SPACE_WIDTH = 2;

View file

@ -197,9 +197,9 @@ export const checkShouldShowMemo = (memo: Memo, filter: Filter) => {
} }
} else if (type === "DISPLAY_TIME") { } else if (type === "DISPLAY_TIME") {
if (operator === "BEFORE") { if (operator === "BEFORE") {
return memo.displayTs < dayjs(value).valueOf(); return memo.createdTs < dayjs(value).valueOf();
} else { } else {
return memo.displayTs > dayjs(value).valueOf(); return memo.createdTs >= dayjs(value).valueOf();
} }
} else if (type === "VISIBILITY") { } else if (type === "VISIBILITY") {
let matched = memo.visibility === value; let matched = memo.visibility === value;

View file

@ -48,7 +48,7 @@ const EmbedMemo = () => {
<main className="w-full max-w-lg mx-auto my-auto shadow px-4 py-4 rounded-lg"> <main className="w-full max-w-lg mx-auto my-auto shadow px-4 py-4 rounded-lg">
<div className="w-full flex flex-col justify-start items-start"> <div className="w-full flex flex-col justify-start items-start">
<div className="w-full mb-2 flex flex-row justify-start items-center text-sm text-gray-400 dark:text-gray-300"> <div className="w-full mb-2 flex flex-row justify-start items-center text-sm text-gray-400 dark:text-gray-300">
<span>{dayjs(state.memo.displayTs).locale(i18n.language).format("YYYY/MM/DD HH:mm:ss")}</span> <span>{dayjs(state.memo.createdTs).locale(i18n.language).format("YYYY/MM/DD HH:mm:ss")}</span>
<a className="ml-2 hover:underline hover:text-green-600" href={`/u/${state.memo.creator.id}`}> <a className="ml-2 hover:underline hover:text-green-600" href={`/u/${state.memo.creator.id}`}>
@{state.memo.creator.nickname || state.memo.creator.username} @{state.memo.creator.nickname || state.memo.creator.username}
</a> </a>

View file

@ -76,7 +76,7 @@ const Explore = () => {
const sortedMemos = shownMemos const sortedMemos = shownMemos
.filter((m) => m.rowStatus === "NORMAL") .filter((m) => m.rowStatus === "NORMAL")
.sort((mi: Memo, mj: Memo) => { .sort((mi: Memo, mj: Memo) => {
return mj.displayTs - mi.displayTs; return mj.createdTs - mi.createdTs;
}); });
const handleFetchMoreClick = async () => { const handleFetchMoreClick = async () => {
@ -141,7 +141,7 @@ const Explore = () => {
<main className="memos-wrapper"> <main className="memos-wrapper">
<MemoFilter /> <MemoFilter />
{sortedMemos.map((memo) => { {sortedMemos.map((memo) => {
const createdAtStr = dayjs(memo.displayTs).locale(i18n.language).format("YYYY/MM/DD HH:mm:ss"); const createdAtStr = dayjs(memo.createdTs).locale(i18n.language).format("YYYY/MM/DD HH:mm:ss");
return ( return (
<div className="memo-container" key={memo.id}> <div className="memo-container" key={memo.id}>
<div className="memo-header"> <div className="memo-header">

View file

@ -78,7 +78,7 @@ const MemoDetail = () => {
<div className="memo-container"> <div className="memo-container">
<div className="memo-header"> <div className="memo-header">
<div className="status-container"> <div className="status-container">
<span className="time-text">{dayjs(state.memo.displayTs).locale(i18n.language).format("YYYY/MM/DD HH:mm:ss")}</span> <span className="time-text">{dayjs(state.memo.createdTs).locale(i18n.language).format("YYYY/MM/DD HH:mm:ss")}</span>
<a className="name-text" href={`/u/${state.memo.creator.id}`}> <a className="name-text" href={`/u/${state.memo.creator.id}`}>
@{state.memo.creator.nickname || state.memo.creator.username} @{state.memo.creator.nickname || state.memo.creator.username}
</a> </a>

View file

@ -10,7 +10,6 @@ const convertResponseModelMemo = (memo: Memo): Memo => {
...memo, ...memo,
createdTs: memo.createdTs * 1000, createdTs: memo.createdTs * 1000,
updatedTs: memo.updatedTs * 1000, updatedTs: memo.updatedTs * 1000,
displayTs: memo.displayTs * 1000,
}; };
}; };

View file

@ -10,7 +10,6 @@ const defaultSetting: Setting = {
locale: "en", locale: "en",
appearance: getSystemColorScheme(), appearance: getSystemColorScheme(),
memoVisibility: "PRIVATE", memoVisibility: "PRIVATE",
memoDisplayTsOption: "created_ts",
}; };
const defaultLocalSetting: LocalSetting = { const defaultLocalSetting: LocalSetting = {

View file

@ -13,7 +13,6 @@ interface Memo {
content: string; content: string;
visibility: Visibility; visibility: Visibility;
pinned: boolean; pinned: boolean;
displayTs: TimeStamp;
creator: User; creator: User;
resourceList: Resource[]; resourceList: Resource[];

View file

@ -4,7 +4,6 @@ interface Setting {
locale: Locale; locale: Locale;
appearance: Appearance; appearance: Appearance;
memoVisibility: Visibility; memoVisibility: Visibility;
memoDisplayTsOption: "created_ts" | "updated_ts";
} }
interface LocalSetting { interface LocalSetting {