feat: display memo with updated ts (#1760)

pull/1761/head
boojack 2 years ago committed by GitHub
parent 826541a714
commit e0e59c5831
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -34,6 +34,7 @@ type MemoResponse struct {
UpdatedTs int64 `json:"updatedTs"` UpdatedTs int64 `json:"updatedTs"`
// Domain specific fields // Domain specific fields
DisplayTs int64 `json:"displayTs"`
Content string `json:"content"` Content string `json:"content"`
Visibility Visibility `json:"visibility"` Visibility Visibility `json:"visibility"`
Pinned bool `json:"pinned"` Pinned bool `json:"pinned"`

@ -24,6 +24,8 @@ type SystemStatus struct {
CustomizedProfile CustomizedProfile `json:"customizedProfile"` CustomizedProfile CustomizedProfile `json:"customizedProfile"`
// Storage service ID. // Storage service ID.
StorageServiceID int `json:"storageServiceId"` StorageServiceID int `json:"storageServiceId"`
// Local storage path // Local storage path.
LocalStoragePath string `json:"localStoragePath"` LocalStoragePath string `json:"localStoragePath"`
// Memo display with updated timestamp.
MemoDisplayWithUpdatedTs bool `json:"memoDisplayWithUpdatedTs"`
} }

@ -36,7 +36,8 @@ const (
// SystemSettingOpenAIConfigName is the name of OpenAI config. // SystemSettingOpenAIConfigName is the name of OpenAI config.
SystemSettingOpenAIConfigName SystemSettingName = "openai-config" SystemSettingOpenAIConfigName SystemSettingName = "openai-config"
// SystemSettingTelegramRobotToken is the name of Telegram Robot Token. // SystemSettingTelegramRobotToken is the name of Telegram Robot Token.
SystemSettingTelegramRobotTokenName SystemSettingName = "telegram-robot-token" SystemSettingTelegramRobotTokenName SystemSettingName = "telegram-robot-token"
SystemSettingMemoDisplayWithUpdatedTsName SystemSettingName = "memo-display-with-updated-ts"
) )
// CustomizedProfile is the struct definition for SystemSettingCustomizedProfileName system setting item. // CustomizedProfile is the struct definition for SystemSettingCustomizedProfileName system setting item.
@ -88,6 +89,8 @@ func (key SystemSettingName) String() string {
return "openai-config" return "openai-config"
case SystemSettingTelegramRobotTokenName: case SystemSettingTelegramRobotTokenName:
return "telegram-robot-token" return "telegram-robot-token"
case SystemSettingMemoDisplayWithUpdatedTsName:
return "memo-display-with-updated-ts"
} }
return "" return ""
} }
@ -111,43 +114,36 @@ func (upsert SystemSettingUpsert) Validate() error {
switch settingName := upsert.Name; settingName { switch settingName := upsert.Name; settingName {
case SystemSettingServerIDName: case SystemSettingServerIDName:
return fmt.Errorf("updating %v is not allowed", settingName) return fmt.Errorf("updating %v is not allowed", settingName)
case SystemSettingAllowSignUpName: case SystemSettingAllowSignUpName:
var value bool var value bool
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
return fmt.Errorf(systemSettingUnmarshalError, settingName) return fmt.Errorf(systemSettingUnmarshalError, settingName)
} }
case SystemSettingIgnoreUpgradeName: case SystemSettingIgnoreUpgradeName:
var value bool var value bool
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
return fmt.Errorf(systemSettingUnmarshalError, settingName) return fmt.Errorf(systemSettingUnmarshalError, settingName)
} }
case SystemSettingDisablePublicMemosName: case SystemSettingDisablePublicMemosName:
var value bool var value bool
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
return fmt.Errorf(systemSettingUnmarshalError, settingName) return fmt.Errorf(systemSettingUnmarshalError, settingName)
} }
case SystemSettingMaxUploadSizeMiBName: case SystemSettingMaxUploadSizeMiBName:
var value int var value int
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
return fmt.Errorf(systemSettingUnmarshalError, settingName) return fmt.Errorf(systemSettingUnmarshalError, settingName)
} }
case SystemSettingAdditionalStyleName: case SystemSettingAdditionalStyleName:
var value string var value string
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
return fmt.Errorf(systemSettingUnmarshalError, settingName) return fmt.Errorf(systemSettingUnmarshalError, settingName)
} }
case SystemSettingAdditionalScriptName: case SystemSettingAdditionalScriptName:
var value string var value string
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
return fmt.Errorf(systemSettingUnmarshalError, settingName) return fmt.Errorf(systemSettingUnmarshalError, settingName)
} }
case SystemSettingCustomizedProfileName: case SystemSettingCustomizedProfileName:
customizedProfile := CustomizedProfile{ customizedProfile := CustomizedProfile{
Name: "memos", Name: "memos",
@ -157,7 +153,6 @@ func (upsert SystemSettingUpsert) Validate() error {
Appearance: "system", Appearance: "system",
ExternalURL: "", ExternalURL: "",
} }
if err := json.Unmarshal([]byte(upsert.Value), &customizedProfile); err != nil { if err := json.Unmarshal([]byte(upsert.Value), &customizedProfile); err != nil {
return fmt.Errorf(systemSettingUnmarshalError, settingName) return fmt.Errorf(systemSettingUnmarshalError, settingName)
} }
@ -167,26 +162,22 @@ func (upsert SystemSettingUpsert) Validate() error {
if !slices.Contains(UserSettingAppearanceValue, customizedProfile.Appearance) { if !slices.Contains(UserSettingAppearanceValue, customizedProfile.Appearance) {
return fmt.Errorf(`invalid appearance value for system setting "%v"`, settingName) return fmt.Errorf(`invalid appearance value for system setting "%v"`, settingName)
} }
case SystemSettingStorageServiceIDName: case SystemSettingStorageServiceIDName:
value := DatabaseStorage value := DatabaseStorage
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
return fmt.Errorf(systemSettingUnmarshalError, settingName) return fmt.Errorf(systemSettingUnmarshalError, settingName)
} }
return nil return nil
case SystemSettingLocalStoragePathName: case SystemSettingLocalStoragePathName:
value := "" value := ""
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
return fmt.Errorf(systemSettingUnmarshalError, settingName) return fmt.Errorf(systemSettingUnmarshalError, settingName)
} }
case SystemSettingOpenAIConfigName: case SystemSettingOpenAIConfigName:
value := OpenAIConfig{} value := OpenAIConfig{}
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
return fmt.Errorf(systemSettingUnmarshalError, settingName) return fmt.Errorf(systemSettingUnmarshalError, settingName)
} }
case SystemSettingTelegramRobotTokenName: case SystemSettingTelegramRobotTokenName:
if upsert.Value == "" { if upsert.Value == "" {
return nil return nil
@ -195,11 +186,14 @@ func (upsert SystemSettingUpsert) Validate() error {
if len(fragments) != 2 { if len(fragments) != 2 {
return fmt.Errorf(systemSettingUnmarshalError, settingName) return fmt.Errorf(systemSettingUnmarshalError, settingName)
} }
case SystemSettingMemoDisplayWithUpdatedTsName:
var value bool
if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil {
return fmt.Errorf(systemSettingUnmarshalError, settingName)
}
default: default:
return fmt.Errorf("invalid system setting name") return fmt.Errorf("invalid system setting name")
} }
return nil return nil
} }

@ -609,19 +609,39 @@ func (s *Server) composeMemoMessageToMemoResponse(ctx context.Context, memoMessa
Pinned: memoMessage.Pinned, Pinned: memoMessage.Pinned,
} }
// Compose creator name.
user, err := s.Store.FindUser(ctx, &api.UserFind{ user, err := s.Store.FindUser(ctx, &api.UserFind{
ID: &memoResponse.CreatorID, ID: &memoResponse.CreatorID,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
if user.Nickname != "" { if user.Nickname != "" {
memoResponse.CreatorName = user.Nickname memoResponse.CreatorName = user.Nickname
} else { } else {
memoResponse.CreatorName = user.Username memoResponse.CreatorName = user.Username
} }
// Compose display ts.
memoResponse.DisplayTs = memoResponse.CreatedTs
// Find memo display with updated ts setting.
memoDisplayWithUpdatedTsSetting, err := s.Store.FindSystemSetting(ctx, &api.SystemSettingFind{
Name: api.SystemSettingMemoDisplayWithUpdatedTsName,
})
if err != nil && common.ErrorCode(err) != common.NotFound {
return nil, errors.Wrap(err, "failed to find system setting")
}
if memoDisplayWithUpdatedTsSetting != nil {
memoDisplayWithUpdatedTs := false
err = json.Unmarshal([]byte(memoDisplayWithUpdatedTsSetting.Value), &memoDisplayWithUpdatedTs)
if err != nil {
return nil, errors.Wrap(err, "failed to unmarshal system setting value")
}
if memoDisplayWithUpdatedTs {
memoResponse.DisplayTs = memoResponse.UpdatedTs
}
}
relationList := []*api.MemoRelation{} relationList := []*api.MemoRelation{}
for _, relation := range memoMessage.RelationList { for _, relation := range memoMessage.RelationList {
relationList = append(relationList, convertMemoRelationMessageToMemoRelation(relation)) relationList = append(relationList, convertMemoRelationMessageToMemoRelation(relation))

@ -55,8 +55,9 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
Appearance: "system", Appearance: "system",
ExternalURL: "", ExternalURL: "",
}, },
StorageServiceID: api.DatabaseStorage, StorageServiceID: api.DatabaseStorage,
LocalStoragePath: "assets/{timestamp}_{filename}", LocalStoragePath: "assets/{timestamp}_{filename}",
MemoDisplayWithUpdatedTs: false,
} }
systemSettingList, err := s.Store.FindSystemSettingList(ctx, &api.SystemSettingFind{}) systemSettingList, err := s.Store.FindSystemSettingList(ctx, &api.SystemSettingFind{})
@ -78,35 +79,28 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
switch systemSetting.Name { switch systemSetting.Name {
case api.SystemSettingAllowSignUpName: case api.SystemSettingAllowSignUpName:
systemStatus.AllowSignUp = baseValue.(bool) systemStatus.AllowSignUp = baseValue.(bool)
case api.SystemSettingIgnoreUpgradeName: case api.SystemSettingIgnoreUpgradeName:
systemStatus.IgnoreUpgrade = baseValue.(bool) systemStatus.IgnoreUpgrade = baseValue.(bool)
case api.SystemSettingDisablePublicMemosName: case api.SystemSettingDisablePublicMemosName:
systemStatus.DisablePublicMemos = baseValue.(bool) systemStatus.DisablePublicMemos = baseValue.(bool)
case api.SystemSettingMaxUploadSizeMiBName: case api.SystemSettingMaxUploadSizeMiBName:
systemStatus.MaxUploadSizeMiB = int(baseValue.(float64)) systemStatus.MaxUploadSizeMiB = int(baseValue.(float64))
case api.SystemSettingAdditionalStyleName: case api.SystemSettingAdditionalStyleName:
systemStatus.AdditionalStyle = baseValue.(string) systemStatus.AdditionalStyle = baseValue.(string)
case api.SystemSettingAdditionalScriptName: case api.SystemSettingAdditionalScriptName:
systemStatus.AdditionalScript = baseValue.(string) systemStatus.AdditionalScript = baseValue.(string)
case api.SystemSettingCustomizedProfileName: case api.SystemSettingCustomizedProfileName:
customizedProfile := api.CustomizedProfile{} customizedProfile := api.CustomizedProfile{}
if err := json.Unmarshal([]byte(systemSetting.Value), &customizedProfile); err != nil { if err := json.Unmarshal([]byte(systemSetting.Value), &customizedProfile); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal system setting customized profile value").SetInternal(err) return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal system setting customized profile value").SetInternal(err)
} }
systemStatus.CustomizedProfile = customizedProfile systemStatus.CustomizedProfile = customizedProfile
case api.SystemSettingStorageServiceIDName: case api.SystemSettingStorageServiceIDName:
systemStatus.StorageServiceID = int(baseValue.(float64)) systemStatus.StorageServiceID = int(baseValue.(float64))
case api.SystemSettingLocalStoragePathName: case api.SystemSettingLocalStoragePathName:
systemStatus.LocalStoragePath = baseValue.(string) systemStatus.LocalStoragePath = baseValue.(string)
case api.SystemSettingMemoDisplayWithUpdatedTsName:
systemStatus.MemoDisplayWithUpdatedTs = baseValue.(bool)
default: default:
log.Warn("Unknown system setting name", zap.String("setting name", systemSetting.Name.String())) log.Warn("Unknown system setting name", zap.String("setting name", systemSetting.Name.String()))
} }

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

@ -33,7 +33,7 @@ const Memo: React.FC<Props> = (props: Props) => {
const userStore = useUserStore(); const userStore = useUserStore();
const memoStore = useMemoStore(); const memoStore = useMemoStore();
const memoCacheStore = useMemoCacheStore(); const memoCacheStore = useMemoCacheStore();
const [createdTimeStr, setCreatedTimeStr] = useState<string>(getRelativeTimeString(memo.createdTs)); const [createdTimeStr, setCreatedTimeStr] = useState<string>(getRelativeTimeString(memo.displayTs));
const [relatedMemoList, setRelatedMemoList] = useState<Memo[]>([]); const [relatedMemoList, setRelatedMemoList] = useState<Memo[]>([]);
const memoContainerRef = useRef<HTMLDivElement>(null); const memoContainerRef = useRef<HTMLDivElement>(null);
const isVisitorMode = userStore.isVisitorMode() || readonly; const isVisitorMode = userStore.isVisitorMode() || readonly;
@ -54,9 +54,9 @@ const Memo: React.FC<Props> = (props: Props) => {
useEffect(() => { useEffect(() => {
let intervalFlag: any = -1; let intervalFlag: any = -1;
if (Date.now() - memo.createdTs < 1000 * 60 * 60 * 24) { if (Date.now() - memo.displayTs < 1000 * 60 * 60 * 24) {
intervalFlag = setInterval(() => { intervalFlag = setInterval(() => {
setCreatedTimeStr(getRelativeTimeString(memo.createdTs)); setCreatedTimeStr(getRelativeTimeString(memo.displayTs));
}, 1000 * 1); }, 1000 * 1);
} }

@ -56,7 +56,7 @@ const MemoList = () => {
if ( if (
duration && duration &&
duration.from < duration.to && duration.from < duration.to &&
(getTimeStampByDate(memo.createdTs) < duration.from || getTimeStampByDate(memo.createdTs) > duration.to) (getTimeStampByDate(memo.displayTs) < duration.from || getTimeStampByDate(memo.displayTs) > duration.to)
) { ) {
shouldShow = false; shouldShow = false;
} }
@ -82,7 +82,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.createdTs - mi.createdTs; return mj.displayTs - mi.displayTs;
}; };
pinnedMemos.sort(memoSort); pinnedMemos.sort(memoSort);
unpinnedMemos.sort(memoSort); unpinnedMemos.sort(memoSort);
@ -168,7 +168,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.createdTs}`} memo={memo} /> <Memo key={`${memo.id}-${memo.displayTs}`} memo={memo} />
))} ))}
{isFetching ? ( {isFetching ? (
<div className="status-text-container fetching-tip"> <div className="status-text-container fetching-tip">

@ -17,6 +17,7 @@ interface State {
additionalStyle: string; additionalStyle: string;
additionalScript: string; additionalScript: string;
maxUploadSizeMiB: number; maxUploadSizeMiB: number;
memoDisplayWithUpdatedTs: boolean;
} }
const SystemSection = () => { const SystemSection = () => {
@ -31,6 +32,7 @@ const SystemSection = () => {
additionalScript: systemStatus.additionalScript, additionalScript: systemStatus.additionalScript,
disablePublicMemos: systemStatus.disablePublicMemos, disablePublicMemos: systemStatus.disablePublicMemos,
maxUploadSizeMiB: systemStatus.maxUploadSizeMiB, maxUploadSizeMiB: systemStatus.maxUploadSizeMiB,
memoDisplayWithUpdatedTs: systemStatus.memoDisplayWithUpdatedTs,
}); });
const [telegramRobotToken, setTelegramRobotToken] = useState<string>(""); const [telegramRobotToken, setTelegramRobotToken] = useState<string>("");
const [openAIConfig, setOpenAIConfig] = useState<OpenAIConfig>({ const [openAIConfig, setOpenAIConfig] = useState<OpenAIConfig>({
@ -65,6 +67,7 @@ const SystemSection = () => {
additionalScript: systemStatus.additionalScript, additionalScript: systemStatus.additionalScript,
disablePublicMemos: systemStatus.disablePublicMemos, disablePublicMemos: systemStatus.disablePublicMemos,
maxUploadSizeMiB: systemStatus.maxUploadSizeMiB, maxUploadSizeMiB: systemStatus.maxUploadSizeMiB,
memoDisplayWithUpdatedTs: systemStatus.memoDisplayWithUpdatedTs,
}); });
}, [systemStatus]); }, [systemStatus]);
@ -202,6 +205,18 @@ const SystemSection = () => {
}); });
}; };
const handleMemoDisplayWithUpdatedTs = async (value: boolean) => {
setState({
...state,
memoDisplayWithUpdatedTs: value,
});
globalStore.setSystemStatus({ disablePublicMemos: value });
await api.upsertSystemSetting({
name: "memo-display-with-updated-ts",
value: JSON.stringify(value),
});
};
const handleMaxUploadSizeChanged = async (event: React.FocusEvent<HTMLInputElement>) => { const handleMaxUploadSizeChanged = async (event: React.FocusEvent<HTMLInputElement>) => {
// fixes cursor skipping position on mobile // fixes cursor skipping position on mobile
event.target.selectionEnd = event.target.value.length; event.target.selectionEnd = event.target.value.length;
@ -254,6 +269,10 @@ const SystemSection = () => {
<span className="normal-text">{t("setting.system-section.disable-public-memos")}</span> <span className="normal-text">{t("setting.system-section.disable-public-memos")}</span>
<Switch checked={state.disablePublicMemos} onChange={(event) => handleDisablePublicMemosChanged(event.target.checked)} /> <Switch checked={state.disablePublicMemos} onChange={(event) => handleDisablePublicMemosChanged(event.target.checked)} />
</div> </div>
<div className="form-label">
<span className="normal-text">Display with updated time</span>
<Switch checked={state.memoDisplayWithUpdatedTs} onChange={(event) => handleMemoDisplayWithUpdatedTs(event.target.checked)} />
</div>
<div className="form-label"> <div className="form-label">
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
<span className="text-sm mr-1">{t("setting.system-section.max-upload-size")}</span> <span className="text-sm mr-1">{t("setting.system-section.max-upload-size")}</span>

@ -46,7 +46,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: getDateTimeString(propsMemo.createdTs), displayTsStr: getDateTimeString(propsMemo.displayTs),
}; };
const createdDays = Math.ceil((Date.now() - getTimeStampByDate(user.createdTs)) / 1000 / 3600 / 24); const createdDays = Math.ceil((Date.now() - getTimeStampByDate(user.createdTs)) / 1000 / 3600 / 24);
@ -174,7 +174,7 @@ const ShareMemoDialog: React.FC<Props> = (props: Props) => {
className="w-full h-auto select-none relative flex flex-col justify-start items-start bg-white dark:bg-zinc-800" className="w-full h-auto select-none relative flex flex-col justify-start items-start bg-white dark:bg-zinc-800"
ref={memoElRef} ref={memoElRef}
> >
<span className="w-full px-6 pt-5 pb-2 text-sm text-gray-500">{memo.createdAtStr}</span> <span className="w-full px-6 pt-5 pb-2 text-sm text-gray-500">{memo.displayTsStr}</span>
<div className="w-full px-6 text-base pb-4"> <div className="w-full px-6 text-base pb-4">
<MemoContent content={memo.content} showFull={true} /> <MemoContent content={memo.content} showFull={true} />
<MemoResourceListView className="!grid-cols-2" resourceList={memo.resourceList} /> <MemoResourceListView className="!grid-cols-2" resourceList={memo.resourceList} />

@ -203,9 +203,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.createdTs < getUnixTimeMillis(value); return memo.displayTs < getUnixTimeMillis(value);
} else { } else {
return memo.createdTs >= getUnixTimeMillis(value); return memo.displayTs >= getUnixTimeMillis(value);
} }
} else if (type === "VISIBILITY") { } else if (type === "VISIBILITY") {
let matched = memo.visibility === value; let matched = memo.visibility === value;

@ -28,15 +28,15 @@ const DailyReview = () => {
const currentDate = new Date(currentDateStamp); const currentDate = new Date(currentDateStamp);
const dailyMemos = memos const dailyMemos = memos
.filter((m) => { .filter((m) => {
const createdTimestamp = getTimeStampByDate(m.createdTs); const displayTimestamp = getTimeStampByDate(m.displayTs);
const currentDateStampWithOffset = currentDateStamp + convertToMillis(localSetting); const currentDateStampWithOffset = currentDateStamp + convertToMillis(localSetting);
return ( return (
m.rowStatus === "NORMAL" && m.rowStatus === "NORMAL" &&
createdTimestamp >= currentDateStampWithOffset && displayTimestamp >= currentDateStampWithOffset &&
createdTimestamp < currentDateStampWithOffset + DAILY_TIMESTAMP displayTimestamp < currentDateStampWithOffset + DAILY_TIMESTAMP
); );
}) })
.sort((a, b) => getTimeStampByDate(a.createdTs) - getTimeStampByDate(b.createdTs)); .sort((a, b) => getTimeStampByDate(a.displayTs) - getTimeStampByDate(b.displayTs));
useEffect(() => { useEffect(() => {
let offset = 0; let offset = 0;
@ -46,7 +46,7 @@ const DailyReview = () => {
offset += fetchedMemos.length; offset += fetchedMemos.length;
if (fetchedMemos.length === DEFAULT_MEMO_LIMIT) { if (fetchedMemos.length === DEFAULT_MEMO_LIMIT) {
const lastMemo = last(fetchedMemos); const lastMemo = last(fetchedMemos);
if (lastMemo && lastMemo.createdTs > currentDateStamp) { if (lastMemo && lastMemo.displayTs > currentDateStamp) {
await fetchMoreMemos(); await fetchMoreMemos();
} }
} }

@ -45,7 +45,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>{getDateTimeString(state.memo.createdTs)}</span> <span>{getDateTimeString(state.memo.displayTs)}</span>
<a className="ml-2 hover:underline hover:text-green-600" href={`/u/${state.memo.creatorId}`}> <a className="ml-2 hover:underline hover:text-green-600" href={`/u/${state.memo.creatorId}`}>
@{state.memo.creatorName} @{state.memo.creatorName}
</a> </a>

@ -90,7 +90,7 @@ const Explore = () => {
<main className="relative w-full h-auto flex flex-col justify-start items-start -mt-2"> <main className="relative w-full h-auto flex flex-col justify-start items-start -mt-2">
<MemoFilter /> <MemoFilter />
{sortedMemos.map((memo) => { {sortedMemos.map((memo) => {
return <Memo key={`${memo.id}-${memo.createdTs}`} memo={memo} readonly={true} />; return <Memo key={`${memo.id}-${memo.displayTs}`} memo={memo} readonly={true} />;
})} })}
{isComplete ? ( {isComplete ? (
state.memos.length === 0 ? ( state.memos.length === 0 ? (

@ -16,6 +16,7 @@ export const initialGlobalState = async () => {
maxUploadSizeMiB: 0, maxUploadSizeMiB: 0,
additionalStyle: "", additionalStyle: "",
additionalScript: "", additionalScript: "",
memoDisplayWithUpdatedTs: false,
customizedProfile: { customizedProfile: {
name: "memos", name: "memos",
logoUrl: "/logo.webp", logoUrl: "/logo.webp",

@ -11,6 +11,7 @@ export 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,
}; };
}; };

@ -23,6 +23,7 @@ const globalSlice = createSlice({
disablePublicMemos: false, disablePublicMemos: false,
additionalStyle: "", additionalStyle: "",
additionalScript: "", additionalScript: "",
memoDisplayWithUpdatedTs: false,
customizedProfile: { customizedProfile: {
name: "memos", name: "memos",
logoUrl: "/logo.webp", logoUrl: "/logo.webp",

@ -10,6 +10,7 @@ interface Memo {
updatedTs: TimeStamp; updatedTs: TimeStamp;
rowStatus: RowStatus; rowStatus: RowStatus;
displayTs: TimeStamp;
content: string; content: string;
visibility: Visibility; visibility: Visibility;
pinned: boolean; pinned: boolean;

@ -31,6 +31,7 @@ interface SystemStatus {
customizedProfile: CustomizedProfile; customizedProfile: CustomizedProfile;
storageServiceId: number; storageServiceId: number;
localStoragePath: string; localStoragePath: string;
memoDisplayWithUpdatedTs: boolean;
} }
interface SystemSetting { interface SystemSetting {

Loading…
Cancel
Save