mirror of
https://github.com/usememos/memos.git
synced 2025-02-11 08:50:40 +01:00
chore: update memo service (#1138)
* chore: update memo service * chore: update
This commit is contained in:
parent
42d849abfc
commit
29124f56bb
@ -1,5 +1,8 @@
|
||||
package api
|
||||
|
||||
// MaxContentLength means the max memo content bytes is 1MB.
|
||||
const MaxContentLength = 1 << 30
|
||||
|
||||
// Visibility is the type of a visibility.
|
||||
type Visibility string
|
||||
|
||||
@ -37,7 +40,6 @@ type Memo struct {
|
||||
Content string `json:"content"`
|
||||
Visibility Visibility `json:"visibility"`
|
||||
Pinned bool `json:"pinned"`
|
||||
DisplayTs int64 `json:"displayTs"`
|
||||
|
||||
// Related fields
|
||||
Creator *User `json:"creator"`
|
||||
@ -86,8 +88,8 @@ type MemoFind struct {
|
||||
VisibilityList []Visibility
|
||||
|
||||
// Pagination
|
||||
Limit int
|
||||
Offset int
|
||||
Limit *int
|
||||
Offset *int
|
||||
}
|
||||
|
||||
type MemoDelete struct {
|
||||
|
@ -16,8 +16,6 @@ const (
|
||||
UserSettingAppearanceKey UserSettingKey = "appearance"
|
||||
// UserSettingMemoVisibilityKey is the key type for user preference memo default visibility.
|
||||
UserSettingMemoVisibilityKey UserSettingKey = "memoVisibility"
|
||||
// UserSettingMemoDisplayTsOptionKey is the key type for memo display ts option.
|
||||
UserSettingMemoDisplayTsOptionKey UserSettingKey = "memoDisplayTsOption"
|
||||
)
|
||||
|
||||
// String returns the string format of UserSettingKey type.
|
||||
@ -29,17 +27,14 @@ func (key UserSettingKey) String() string {
|
||||
return "appearance"
|
||||
case UserSettingMemoVisibilityKey:
|
||||
return "memoVisibility"
|
||||
case UserSettingMemoDisplayTsOptionKey:
|
||||
return "memoDisplayTsOption"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var (
|
||||
UserSettingLocaleValue = []string{"en", "zh", "vi", "fr", "nl", "sv", "de", "es", "uk", "ru", "it", "hant", "ko"}
|
||||
UserSettingAppearanceValue = []string{"system", "light", "dark"}
|
||||
UserSettingMemoVisibilityValue = []Visibility{Private, Protected, Public}
|
||||
UserSettingMemoDisplayTsOptionKeyValue = []string{"created_ts", "updated_ts"}
|
||||
UserSettingLocaleValue = []string{"en", "zh", "vi", "fr", "nl", "sv", "de", "es", "uk", "ru", "it", "hant", "ko"}
|
||||
UserSettingAppearanceValue = []string{"system", "light", "dark"}
|
||||
UserSettingMemoVisibilityValue = []Visibility{Private, Protected, Public}
|
||||
)
|
||||
|
||||
type UserSetting struct {
|
||||
@ -83,15 +78,6 @@ func (upsert UserSettingUpsert) Validate() error {
|
||||
if !slices.Contains(UserSettingMemoVisibilityValue, memoVisibilityValue) {
|
||||
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 {
|
||||
return fmt.Errorf("invalid user setting key")
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"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
|
||||
memo, err := s.Store.CreateMemo(ctx, memoCreate)
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
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 {
|
||||
memoFind.Offset = offset
|
||||
memoFind.Offset = &offset
|
||||
}
|
||||
|
||||
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 = append(memoList, pinnedMemoList...)
|
||||
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))
|
||||
})
|
||||
|
||||
@ -399,11 +395,11 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to fetch memo list").SetInternal(err)
|
||||
}
|
||||
|
||||
displayTsList := []int64{}
|
||||
createdTsList := []int64{}
|
||||
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 {
|
||||
@ -436,10 +432,10 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
|
||||
memoFind.VisibilityList = visibilityList
|
||||
}
|
||||
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 {
|
||||
memoFind.Offset = offset
|
||||
memoFind.Offset = &offset
|
||||
}
|
||||
|
||||
// Only fetch normal status memos.
|
||||
@ -450,14 +446,6 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
|
||||
if err != nil {
|
||||
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))
|
||||
})
|
||||
|
||||
|
@ -3,7 +3,6 @@ package store
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@ -43,7 +42,6 @@ func (raw *memoRaw) toMemo() *api.Memo {
|
||||
// Domain specific fields
|
||||
Content: raw.Content,
|
||||
Visibility: raw.Visibility,
|
||||
DisplayTs: raw.CreatedTs,
|
||||
Pinned: raw.Pinned,
|
||||
}
|
||||
}
|
||||
@ -56,25 +54,6 @@ func (s *Store) ComposeMemo(ctx context.Context, memo *api.Memo) (*api.Memo, 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
|
||||
}
|
||||
|
||||
@ -329,6 +308,13 @@ func findMemoRawList(ctx context.Context, tx *sql.Tx, find *api.MemoFind) ([]*me
|
||||
WHERE ` + strings.Join(where, " AND ") + `
|
||||
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...)
|
||||
if err != nil {
|
||||
return nil, FormatError(err)
|
||||
|
@ -9,7 +9,7 @@ interface Props {
|
||||
|
||||
const DailyMemo: React.FC<Props> = (props: Props) => {
|
||||
const { memo } = props;
|
||||
const displayTimeStr = utils.getTimeString(memo.displayTs);
|
||||
const createdTimeStr = utils.getTimeString(memo.createdTs);
|
||||
const displayConfig: DisplayConfig = {
|
||||
enableExpand: false,
|
||||
};
|
||||
@ -17,7 +17,7 @@ const DailyMemo: React.FC<Props> = (props: Props) => {
|
||||
return (
|
||||
<div className="daily-memo-wrapper">
|
||||
<div className="time-wrapper">
|
||||
<span className="normal-text">{displayTimeStr}</span>
|
||||
<span className="normal-text">{createdTimeStr}</span>
|
||||
</div>
|
||||
<div className="memo-container">
|
||||
<MemoContent content={memo.content} displayConfig={displayConfig} />
|
||||
|
@ -31,10 +31,10 @@ const DailyReviewDialog: React.FC<Props> = (props: Props) => {
|
||||
.filter(
|
||||
(m) =>
|
||||
m.rowStatus === "NORMAL" &&
|
||||
utils.getTimeStampByDate(m.displayTs) >= currentDateStamp &&
|
||||
utils.getTimeStampByDate(m.displayTs) < currentDateStamp + DAILY_TIMESTAMP
|
||||
utils.getTimeStampByDate(m.createdTs) >= currentDateStamp &&
|
||||
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 = () => {
|
||||
if (!memosElRef.current) {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import copy from "copy-to-clipboard";
|
||||
import dayjs from "dayjs";
|
||||
import { memo, useEffect, useRef, useState } from "react";
|
||||
@ -34,15 +35,16 @@ const Memo: React.FC<Props> = (props: Props) => {
|
||||
const locationStore = useLocationStore();
|
||||
const userStore = useUserStore();
|
||||
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 isVisitorMode = userStore.isVisitorMode();
|
||||
const updatedTimeStr = getFormatedMemoTimeStr(memo.updatedTs, i18n.language);
|
||||
|
||||
useEffect(() => {
|
||||
let intervalFlag: any = -1;
|
||||
if (Date.now() - memo.displayTs < 1000 * 60 * 60 * 24) {
|
||||
if (Date.now() - memo.createdTs < 1000 * 60 * 60 * 24) {
|
||||
intervalFlag = setInterval(() => {
|
||||
setDisplayTimeStr(getFormatedMemoTimeStr(memo.displayTs, i18n.language));
|
||||
setCreatedTimeStr(getFormatedMemoTimeStr(memo.createdTs, i18n.language));
|
||||
}, 1000 * 1);
|
||||
}
|
||||
|
||||
@ -166,7 +168,7 @@ const Memo: React.FC<Props> = (props: Props) => {
|
||||
editorStore.setEditMemoWithId(memo.id);
|
||||
};
|
||||
|
||||
const handleMemoDisplayTimeClick = () => {
|
||||
const handleMemoCreatedTimeClick = () => {
|
||||
showChangeMemoCreatedTsDialog(memo.id);
|
||||
};
|
||||
|
||||
@ -184,9 +186,11 @@ const Memo: React.FC<Props> = (props: Props) => {
|
||||
{memo.pinned && <div className="corner-container"></div>}
|
||||
<div className="memo-top-wrapper">
|
||||
<div className="status-text-container">
|
||||
<span className="time-text" onDoubleClick={handleMemoDisplayTimeClick}>
|
||||
{displayTimeStr}
|
||||
</span>
|
||||
<Tooltip title={`Updated at ${updatedTimeStr}`} placement="top" arrow>
|
||||
<span className="time-text" onDoubleClick={handleMemoCreatedTimeClick}>
|
||||
{createdTimeStr}
|
||||
</span>
|
||||
</Tooltip>
|
||||
{memo.visibility !== "PRIVATE" && !isVisitorMode && (
|
||||
<span
|
||||
className={`status-text ${memo.visibility.toLocaleLowerCase()}`}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from "react";
|
||||
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 * as utils from "../helpers/utils";
|
||||
import { DEFAULT_MEMO_LIMIT } from "../helpers/consts";
|
||||
@ -11,12 +11,10 @@ import "../less/memo-list.less";
|
||||
|
||||
const MemoList = () => {
|
||||
const { t } = useTranslation();
|
||||
const userStore = useUserStore();
|
||||
const memoStore = useMemoStore();
|
||||
const shortcutStore = useShortcutStore();
|
||||
const locationStore = useLocationStore();
|
||||
const query = locationStore.state.query;
|
||||
const memoDisplayTsOption = userStore.state.user?.setting.memoDisplayTsOption;
|
||||
const { memos, isFetching } = memoStore.state;
|
||||
const [isComplete, setIsComplete] = useState<boolean>(false);
|
||||
|
||||
@ -54,7 +52,7 @@ const MemoList = () => {
|
||||
if (
|
||||
duration &&
|
||||
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;
|
||||
}
|
||||
@ -79,7 +77,7 @@ const MemoList = () => {
|
||||
const pinnedMemos = shownMemos.filter((m) => m.pinned);
|
||||
const unpinnedMemos = shownMemos.filter((m) => !m.pinned);
|
||||
const memoSort = (mi: Memo, mj: Memo) => {
|
||||
return mj.displayTs - mi.displayTs;
|
||||
return mj.createdTs - mi.createdTs;
|
||||
};
|
||||
pinnedMemos.sort(memoSort);
|
||||
unpinnedMemos.sort(memoSort);
|
||||
@ -99,7 +97,7 @@ const MemoList = () => {
|
||||
console.error(error);
|
||||
toastHelper.error(error.response.data.message);
|
||||
});
|
||||
}, [memoDisplayTsOption]);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const pageWrapper = document.body.querySelector(".page-wrapper");
|
||||
@ -134,7 +132,7 @@ const MemoList = () => {
|
||||
return (
|
||||
<div className="memo-list-container">
|
||||
{sortedMemos.map((memo) => (
|
||||
<Memo key={`${memo.id}-${memo.displayTs}`} memo={memo} />
|
||||
<Memo key={`${memo.id}-${memo.createdTs}`} memo={memo} />
|
||||
))}
|
||||
{isFetching ? (
|
||||
<div className="status-text-container fetching-tip">
|
||||
|
@ -2,7 +2,7 @@ import { Select, Switch, Option } from "@mui/joy";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
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 LocaleSelect from "../LocaleSelect";
|
||||
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) => {
|
||||
await userStore.upsertUserSetting("locale", locale);
|
||||
globalStore.setLocale(locale);
|
||||
@ -41,10 +34,6 @@ const PreferencesSection = () => {
|
||||
await userStore.upsertUserSetting("memoVisibility", value);
|
||||
};
|
||||
|
||||
const handleMemoDisplayTsOptionChanged = async (value: string) => {
|
||||
await userStore.upsertUserSetting("memoDisplayTsOption", value);
|
||||
};
|
||||
|
||||
const handleIsFoldingEnabledChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
userStore.upsertLocalSetting({ ...localSetting, enableFoldMemo: event.target.checked });
|
||||
};
|
||||
@ -83,24 +72,6 @@ const PreferencesSection = () => {
|
||||
))}
|
||||
</Select>
|
||||
</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">
|
||||
<span className="normal-text">{t("setting.preference-section.enable-folding-memo")}</span>
|
||||
<Switch className="ml-2" checked={localSetting.enableFoldMemo} onChange={handleIsFoldingEnabledChanged} />
|
||||
|
@ -44,7 +44,7 @@ const ShareMemoDialog: React.FC<Props> = (props: Props) => {
|
||||
const memoElRef = useRef<HTMLDivElement>(null);
|
||||
const memo = {
|
||||
...propsMemo,
|
||||
createdAtStr: utils.getDateTimeString(propsMemo.displayTs),
|
||||
createdAtStr: utils.getDateTimeString(propsMemo.createdTs),
|
||||
};
|
||||
const createdDays = Math.ceil((Date.now() - utils.getTimeStampByDate(user.createdTs)) / 1000 / 3600 / 24);
|
||||
|
||||
|
@ -13,11 +13,6 @@ export const VISIBILITY_SELECTOR_ITEMS = [
|
||||
{ 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
|
||||
export const TAB_SPACE_WIDTH = 2;
|
||||
|
||||
|
@ -197,9 +197,9 @@ export const checkShouldShowMemo = (memo: Memo, filter: Filter) => {
|
||||
}
|
||||
} else if (type === "DISPLAY_TIME") {
|
||||
if (operator === "BEFORE") {
|
||||
return memo.displayTs < dayjs(value).valueOf();
|
||||
return memo.createdTs < dayjs(value).valueOf();
|
||||
} else {
|
||||
return memo.displayTs > dayjs(value).valueOf();
|
||||
return memo.createdTs >= dayjs(value).valueOf();
|
||||
}
|
||||
} else if (type === "VISIBILITY") {
|
||||
let matched = memo.visibility === value;
|
||||
|
@ -48,7 +48,7 @@ const EmbedMemo = () => {
|
||||
<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 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}`}>
|
||||
@{state.memo.creator.nickname || state.memo.creator.username}
|
||||
</a>
|
||||
|
@ -76,7 +76,7 @@ const Explore = () => {
|
||||
const sortedMemos = shownMemos
|
||||
.filter((m) => m.rowStatus === "NORMAL")
|
||||
.sort((mi: Memo, mj: Memo) => {
|
||||
return mj.displayTs - mi.displayTs;
|
||||
return mj.createdTs - mi.createdTs;
|
||||
});
|
||||
|
||||
const handleFetchMoreClick = async () => {
|
||||
@ -141,7 +141,7 @@ const Explore = () => {
|
||||
<main className="memos-wrapper">
|
||||
<MemoFilter />
|
||||
{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 (
|
||||
<div className="memo-container" key={memo.id}>
|
||||
<div className="memo-header">
|
||||
|
@ -78,7 +78,7 @@ const MemoDetail = () => {
|
||||
<div className="memo-container">
|
||||
<div className="memo-header">
|
||||
<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}`}>
|
||||
@{state.memo.creator.nickname || state.memo.creator.username}
|
||||
</a>
|
||||
|
@ -10,7 +10,6 @@ const convertResponseModelMemo = (memo: Memo): Memo => {
|
||||
...memo,
|
||||
createdTs: memo.createdTs * 1000,
|
||||
updatedTs: memo.updatedTs * 1000,
|
||||
displayTs: memo.displayTs * 1000,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,6 @@ const defaultSetting: Setting = {
|
||||
locale: "en",
|
||||
appearance: getSystemColorScheme(),
|
||||
memoVisibility: "PRIVATE",
|
||||
memoDisplayTsOption: "created_ts",
|
||||
};
|
||||
|
||||
const defaultLocalSetting: LocalSetting = {
|
||||
|
1
web/src/types/modules/memo.d.ts
vendored
1
web/src/types/modules/memo.d.ts
vendored
@ -13,7 +13,6 @@ interface Memo {
|
||||
content: string;
|
||||
visibility: Visibility;
|
||||
pinned: boolean;
|
||||
displayTs: TimeStamp;
|
||||
|
||||
creator: User;
|
||||
resourceList: Resource[];
|
||||
|
1
web/src/types/modules/setting.d.ts
vendored
1
web/src/types/modules/setting.d.ts
vendored
@ -4,7 +4,6 @@ interface Setting {
|
||||
locale: Locale;
|
||||
appearance: Appearance;
|
||||
memoVisibility: Visibility;
|
||||
memoDisplayTsOption: "created_ts" | "updated_ts";
|
||||
}
|
||||
|
||||
interface LocalSetting {
|
||||
|
Loading…
x
Reference in New Issue
Block a user