Commit 671551bd authored by Steven's avatar Steven

chore: update memo detail page

parent 10c81ccb
...@@ -3,6 +3,7 @@ package v2 ...@@ -3,6 +3,7 @@ package v2
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"time" "time"
"github.com/google/cel-go/cel" "github.com/google/cel-go/cel"
...@@ -289,7 +290,12 @@ func (s *APIV2Service) ListMemoResources(ctx context.Context, request *apiv2pb.L ...@@ -289,7 +290,12 @@ func (s *APIV2Service) ListMemoResources(ctx context.Context, request *apiv2pb.L
} }
func (s *APIV2Service) SetMemoRelations(ctx context.Context, request *apiv2pb.SetMemoRelationsRequest) (*apiv2pb.SetMemoRelationsResponse, error) { func (s *APIV2Service) SetMemoRelations(ctx context.Context, request *apiv2pb.SetMemoRelationsRequest) (*apiv2pb.SetMemoRelationsResponse, error) {
if err := s.Store.DeleteMemoRelation(ctx, &store.DeleteMemoRelation{MemoID: &request.Id}); err != nil { referenceType := store.MemoRelationReference
// Delete all reference relations first.
if err := s.Store.DeleteMemoRelation(ctx, &store.DeleteMemoRelation{
MemoID: &request.Id,
Type: &referenceType,
}); err != nil {
return nil, status.Errorf(codes.Internal, "failed to delete memo relation") return nil, status.Errorf(codes.Internal, "failed to delete memo relation")
} }
...@@ -400,13 +406,19 @@ func (s *APIV2Service) convertMemoFromStore(ctx context.Context, memo *store.Mem ...@@ -400,13 +406,19 @@ func (s *APIV2Service) convertMemoFromStore(ctx context.Context, memo *store.Mem
displayTs = memo.UpdatedTs displayTs = memo.UpdatedTs
} }
creator, err := s.Store.GetUser(ctx, &store.FindUser{ID: &memo.CreatorID})
if err != nil {
return nil, errors.Wrap(err, "failed to get creator")
}
return &apiv2pb.Memo{ return &apiv2pb.Memo{
Id: int32(memo.ID), Id: int32(memo.ID),
RowStatus: convertRowStatusFromStore(memo.RowStatus), RowStatus: convertRowStatusFromStore(memo.RowStatus),
Creator: fmt.Sprintf("%s%s", UserNamePrefix, creator.Username),
CreatorId: int32(memo.CreatorID),
CreateTime: timestamppb.New(time.Unix(memo.CreatedTs, 0)), CreateTime: timestamppb.New(time.Unix(memo.CreatedTs, 0)),
UpdateTime: timestamppb.New(time.Unix(memo.UpdatedTs, 0)), UpdateTime: timestamppb.New(time.Unix(memo.UpdatedTs, 0)),
DisplayTime: timestamppb.New(time.Unix(displayTs, 0)), DisplayTime: timestamppb.New(time.Unix(displayTs, 0)),
CreatorId: int32(memo.CreatorID),
Content: memo.Content, Content: memo.Content,
Nodes: convertFromASTNodes(rawNodes), Nodes: convertFromASTNodes(rawNodes),
Visibility: convertVisibilityFromStore(memo.Visibility), Visibility: convertVisibilityFromStore(memo.Visibility),
......
...@@ -14,22 +14,23 @@ import "google/protobuf/timestamp.proto"; ...@@ -14,22 +14,23 @@ import "google/protobuf/timestamp.proto";
option go_package = "gen/api/v2"; option go_package = "gen/api/v2";
service MemoService { service MemoService {
// CreateMemo creates a memo.
rpc CreateMemo(CreateMemoRequest) returns (CreateMemoResponse) { rpc CreateMemo(CreateMemoRequest) returns (CreateMemoResponse) {
option (google.api.http) = { option (google.api.http) = {
post: "/api/v2/memos" post: "/api/v2/memos"
body: "*" body: "*"
}; };
} }
// ListMemos lists memos with pagination and filter.
rpc ListMemos(ListMemosRequest) returns (ListMemosResponse) { rpc ListMemos(ListMemosRequest) returns (ListMemosResponse) {
option (google.api.http) = {get: "/api/v2/memos"}; option (google.api.http) = {get: "/api/v2/memos"};
} }
// GetMemo gets a memo by id.
rpc GetMemo(GetMemoRequest) returns (GetMemoResponse) { rpc GetMemo(GetMemoRequest) returns (GetMemoResponse) {
option (google.api.http) = {get: "/api/v2/memos/{id}"}; option (google.api.http) = {get: "/api/v2/memos/{id}"};
option (google.api.method_signature) = "id"; option (google.api.method_signature) = "id";
} }
// UpdateMemo updates a memo.
rpc UpdateMemo(UpdateMemoRequest) returns (UpdateMemoResponse) { rpc UpdateMemo(UpdateMemoRequest) returns (UpdateMemoResponse) {
option (google.api.http) = { option (google.api.http) = {
patch: "/api/v2/memos/{id}" patch: "/api/v2/memos/{id}"
...@@ -37,12 +38,12 @@ service MemoService { ...@@ -37,12 +38,12 @@ service MemoService {
}; };
option (google.api.method_signature) = "id, update_mask"; option (google.api.method_signature) = "id, update_mask";
} }
// DeleteMemo deletes a memo by id.
rpc DeleteMemo(DeleteMemoRequest) returns (DeleteMemoResponse) { rpc DeleteMemo(DeleteMemoRequest) returns (DeleteMemoResponse) {
option (google.api.http) = {delete: "/api/v2/memos/{id}"}; option (google.api.http) = {delete: "/api/v2/memos/{id}"};
option (google.api.method_signature) = "id"; option (google.api.method_signature) = "id";
} }
// SetMemoResources sets resources for a memo.
rpc SetMemoResources(SetMemoResourcesRequest) returns (SetMemoResourcesResponse) { rpc SetMemoResources(SetMemoResourcesRequest) returns (SetMemoResourcesResponse) {
option (google.api.http) = { option (google.api.http) = {
post: "/api/v2/memos/{id}/resources" post: "/api/v2/memos/{id}/resources"
...@@ -50,12 +51,12 @@ service MemoService { ...@@ -50,12 +51,12 @@ service MemoService {
}; };
option (google.api.method_signature) = "id"; option (google.api.method_signature) = "id";
} }
// ListMemoResources lists resources for a memo.
rpc ListMemoResources(ListMemoResourcesRequest) returns (ListMemoResourcesResponse) { rpc ListMemoResources(ListMemoResourcesRequest) returns (ListMemoResourcesResponse) {
option (google.api.http) = {get: "/api/v2/memos/{id}/resources"}; option (google.api.http) = {get: "/api/v2/memos/{id}/resources"};
option (google.api.method_signature) = "id"; option (google.api.method_signature) = "id";
} }
// SetMemoRelations sets relations for a memo.
rpc SetMemoRelations(SetMemoRelationsRequest) returns (SetMemoRelationsResponse) { rpc SetMemoRelations(SetMemoRelationsRequest) returns (SetMemoRelationsResponse) {
option (google.api.http) = { option (google.api.http) = {
post: "/api/v2/memos/{id}/relations" post: "/api/v2/memos/{id}/relations"
...@@ -63,17 +64,17 @@ service MemoService { ...@@ -63,17 +64,17 @@ service MemoService {
}; };
option (google.api.method_signature) = "id"; option (google.api.method_signature) = "id";
} }
// ListMemoRelations lists relations for a memo.
rpc ListMemoRelations(ListMemoRelationsRequest) returns (ListMemoRelationsResponse) { rpc ListMemoRelations(ListMemoRelationsRequest) returns (ListMemoRelationsResponse) {
option (google.api.http) = {get: "/api/v2/memos/{id}/relations"}; option (google.api.http) = {get: "/api/v2/memos/{id}/relations"};
option (google.api.method_signature) = "id"; option (google.api.method_signature) = "id";
} }
// CreateMemoComment creates a comment for a memo.
rpc CreateMemoComment(CreateMemoCommentRequest) returns (CreateMemoCommentResponse) { rpc CreateMemoComment(CreateMemoCommentRequest) returns (CreateMemoCommentResponse) {
option (google.api.http) = {post: "/api/v2/memos/{id}/comments"}; option (google.api.http) = {post: "/api/v2/memos/{id}/comments"};
option (google.api.method_signature) = "id"; option (google.api.method_signature) = "id";
} }
// ListMemoComments lists comments for a memo.
rpc ListMemoComments(ListMemoCommentsRequest) returns (ListMemoCommentsResponse) { rpc ListMemoComments(ListMemoCommentsRequest) returns (ListMemoCommentsResponse) {
option (google.api.http) = {get: "/api/v2/memos/{id}/comments"}; option (google.api.http) = {get: "/api/v2/memos/{id}/comments"};
option (google.api.method_signature) = "id"; option (google.api.method_signature) = "id";
...@@ -95,21 +96,25 @@ message Memo { ...@@ -95,21 +96,25 @@ message Memo {
RowStatus row_status = 2; RowStatus row_status = 2;
int32 creator_id = 3; // The name of the creator.
// Format: users/{username}
string creator = 3;
int32 creator_id = 4;
google.protobuf.Timestamp create_time = 4; google.protobuf.Timestamp create_time = 5;
google.protobuf.Timestamp update_time = 5; google.protobuf.Timestamp update_time = 6;
google.protobuf.Timestamp display_time = 6; google.protobuf.Timestamp display_time = 7;
string content = 7; string content = 8;
repeated Node nodes = 8; repeated Node nodes = 9;
Visibility visibility = 9; Visibility visibility = 10;
bool pinned = 10; bool pinned = 11;
} }
message CreateMemoRequest { message CreateMemoRequest {
...@@ -128,6 +133,7 @@ message ListMemosRequest { ...@@ -128,6 +133,7 @@ message ListMemosRequest {
int32 page_size = 2; int32 page_size = 2;
// Filter is used to filter memos returned in the list. // Filter is used to filter memos returned in the list.
// Format: "creator == users/{username} && visibility == PUBLIC"
string filter = 3; string filter = 3;
} }
......
...@@ -1762,7 +1762,7 @@ ...@@ -1762,7 +1762,7 @@
| ----- | ---- | ----- | ----------- | | ----- | ---- | ----- | ----------- |
| page | [int32](#int32) | | | | page | [int32](#int32) | | |
| page_size | [int32](#int32) | | | | page_size | [int32](#int32) | | |
| filter | [string](#string) | | Filter is used to filter memos returned in the list. | | filter | [string](#string) | | Filter is used to filter memos returned in the list. Format: "creator == users/{username} && visibility == PUBLIC" |
...@@ -1794,6 +1794,7 @@ ...@@ -1794,6 +1794,7 @@
| ----- | ---- | ----- | ----------- | | ----- | ---- | ----- | ----------- |
| id | [int32](#int32) | | | | id | [int32](#int32) | | |
| row_status | [RowStatus](#memos-api-v2-RowStatus) | | | | row_status | [RowStatus](#memos-api-v2-RowStatus) | | |
| creator | [string](#string) | | The name of the creator. Format: users/{username} |
| creator_id | [int32](#int32) | | | | creator_id | [int32](#int32) | | |
| create_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | | create_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | |
| update_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | | update_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | |
...@@ -1919,17 +1920,17 @@ ...@@ -1919,17 +1920,17 @@
| Method Name | Request Type | Response Type | Description | | Method Name | Request Type | Response Type | Description |
| ----------- | ------------ | ------------- | ------------| | ----------- | ------------ | ------------- | ------------|
| CreateMemo | [CreateMemoRequest](#memos-api-v2-CreateMemoRequest) | [CreateMemoResponse](#memos-api-v2-CreateMemoResponse) | | | CreateMemo | [CreateMemoRequest](#memos-api-v2-CreateMemoRequest) | [CreateMemoResponse](#memos-api-v2-CreateMemoResponse) | CreateMemo creates a memo. |
| ListMemos | [ListMemosRequest](#memos-api-v2-ListMemosRequest) | [ListMemosResponse](#memos-api-v2-ListMemosResponse) | | | ListMemos | [ListMemosRequest](#memos-api-v2-ListMemosRequest) | [ListMemosResponse](#memos-api-v2-ListMemosResponse) | ListMemos lists memos with pagination and filter. |
| GetMemo | [GetMemoRequest](#memos-api-v2-GetMemoRequest) | [GetMemoResponse](#memos-api-v2-GetMemoResponse) | | | GetMemo | [GetMemoRequest](#memos-api-v2-GetMemoRequest) | [GetMemoResponse](#memos-api-v2-GetMemoResponse) | GetMemo gets a memo by id. |
| UpdateMemo | [UpdateMemoRequest](#memos-api-v2-UpdateMemoRequest) | [UpdateMemoResponse](#memos-api-v2-UpdateMemoResponse) | | | UpdateMemo | [UpdateMemoRequest](#memos-api-v2-UpdateMemoRequest) | [UpdateMemoResponse](#memos-api-v2-UpdateMemoResponse) | UpdateMemo updates a memo. |
| DeleteMemo | [DeleteMemoRequest](#memos-api-v2-DeleteMemoRequest) | [DeleteMemoResponse](#memos-api-v2-DeleteMemoResponse) | | | DeleteMemo | [DeleteMemoRequest](#memos-api-v2-DeleteMemoRequest) | [DeleteMemoResponse](#memos-api-v2-DeleteMemoResponse) | DeleteMemo deletes a memo by id. |
| SetMemoResources | [SetMemoResourcesRequest](#memos-api-v2-SetMemoResourcesRequest) | [SetMemoResourcesResponse](#memos-api-v2-SetMemoResourcesResponse) | | | SetMemoResources | [SetMemoResourcesRequest](#memos-api-v2-SetMemoResourcesRequest) | [SetMemoResourcesResponse](#memos-api-v2-SetMemoResourcesResponse) | SetMemoResources sets resources for a memo. |
| ListMemoResources | [ListMemoResourcesRequest](#memos-api-v2-ListMemoResourcesRequest) | [ListMemoResourcesResponse](#memos-api-v2-ListMemoResourcesResponse) | | | ListMemoResources | [ListMemoResourcesRequest](#memos-api-v2-ListMemoResourcesRequest) | [ListMemoResourcesResponse](#memos-api-v2-ListMemoResourcesResponse) | ListMemoResources lists resources for a memo. |
| SetMemoRelations | [SetMemoRelationsRequest](#memos-api-v2-SetMemoRelationsRequest) | [SetMemoRelationsResponse](#memos-api-v2-SetMemoRelationsResponse) | | | SetMemoRelations | [SetMemoRelationsRequest](#memos-api-v2-SetMemoRelationsRequest) | [SetMemoRelationsResponse](#memos-api-v2-SetMemoRelationsResponse) | SetMemoRelations sets relations for a memo. |
| ListMemoRelations | [ListMemoRelationsRequest](#memos-api-v2-ListMemoRelationsRequest) | [ListMemoRelationsResponse](#memos-api-v2-ListMemoRelationsResponse) | | | ListMemoRelations | [ListMemoRelationsRequest](#memos-api-v2-ListMemoRelationsRequest) | [ListMemoRelationsResponse](#memos-api-v2-ListMemoRelationsResponse) | ListMemoRelations lists relations for a memo. |
| CreateMemoComment | [CreateMemoCommentRequest](#memos-api-v2-CreateMemoCommentRequest) | [CreateMemoCommentResponse](#memos-api-v2-CreateMemoCommentResponse) | | | CreateMemoComment | [CreateMemoCommentRequest](#memos-api-v2-CreateMemoCommentRequest) | [CreateMemoCommentResponse](#memos-api-v2-CreateMemoCommentResponse) | CreateMemoComment creates a comment for a memo. |
| ListMemoComments | [ListMemoCommentsRequest](#memos-api-v2-ListMemoCommentsRequest) | [ListMemoCommentsResponse](#memos-api-v2-ListMemoCommentsResponse) | | | ListMemoComments | [ListMemoCommentsRequest](#memos-api-v2-ListMemoCommentsRequest) | [ListMemoCommentsResponse](#memos-api-v2-ListMemoCommentsResponse) | ListMemoComments lists comments for a memo. |
......
This diff is collapsed.
...@@ -36,16 +36,27 @@ const ( ...@@ -36,16 +36,27 @@ const (
// //
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type MemoServiceClient interface { type MemoServiceClient interface {
// CreateMemo creates a memo.
CreateMemo(ctx context.Context, in *CreateMemoRequest, opts ...grpc.CallOption) (*CreateMemoResponse, error) CreateMemo(ctx context.Context, in *CreateMemoRequest, opts ...grpc.CallOption) (*CreateMemoResponse, error)
// ListMemos lists memos with pagination and filter.
ListMemos(ctx context.Context, in *ListMemosRequest, opts ...grpc.CallOption) (*ListMemosResponse, error) ListMemos(ctx context.Context, in *ListMemosRequest, opts ...grpc.CallOption) (*ListMemosResponse, error)
// GetMemo gets a memo by id.
GetMemo(ctx context.Context, in *GetMemoRequest, opts ...grpc.CallOption) (*GetMemoResponse, error) GetMemo(ctx context.Context, in *GetMemoRequest, opts ...grpc.CallOption) (*GetMemoResponse, error)
// UpdateMemo updates a memo.
UpdateMemo(ctx context.Context, in *UpdateMemoRequest, opts ...grpc.CallOption) (*UpdateMemoResponse, error) UpdateMemo(ctx context.Context, in *UpdateMemoRequest, opts ...grpc.CallOption) (*UpdateMemoResponse, error)
// DeleteMemo deletes a memo by id.
DeleteMemo(ctx context.Context, in *DeleteMemoRequest, opts ...grpc.CallOption) (*DeleteMemoResponse, error) DeleteMemo(ctx context.Context, in *DeleteMemoRequest, opts ...grpc.CallOption) (*DeleteMemoResponse, error)
// SetMemoResources sets resources for a memo.
SetMemoResources(ctx context.Context, in *SetMemoResourcesRequest, opts ...grpc.CallOption) (*SetMemoResourcesResponse, error) SetMemoResources(ctx context.Context, in *SetMemoResourcesRequest, opts ...grpc.CallOption) (*SetMemoResourcesResponse, error)
// ListMemoResources lists resources for a memo.
ListMemoResources(ctx context.Context, in *ListMemoResourcesRequest, opts ...grpc.CallOption) (*ListMemoResourcesResponse, error) ListMemoResources(ctx context.Context, in *ListMemoResourcesRequest, opts ...grpc.CallOption) (*ListMemoResourcesResponse, error)
// SetMemoRelations sets relations for a memo.
SetMemoRelations(ctx context.Context, in *SetMemoRelationsRequest, opts ...grpc.CallOption) (*SetMemoRelationsResponse, error) SetMemoRelations(ctx context.Context, in *SetMemoRelationsRequest, opts ...grpc.CallOption) (*SetMemoRelationsResponse, error)
// ListMemoRelations lists relations for a memo.
ListMemoRelations(ctx context.Context, in *ListMemoRelationsRequest, opts ...grpc.CallOption) (*ListMemoRelationsResponse, error) ListMemoRelations(ctx context.Context, in *ListMemoRelationsRequest, opts ...grpc.CallOption) (*ListMemoRelationsResponse, error)
// CreateMemoComment creates a comment for a memo.
CreateMemoComment(ctx context.Context, in *CreateMemoCommentRequest, opts ...grpc.CallOption) (*CreateMemoCommentResponse, error) CreateMemoComment(ctx context.Context, in *CreateMemoCommentRequest, opts ...grpc.CallOption) (*CreateMemoCommentResponse, error)
// ListMemoComments lists comments for a memo.
ListMemoComments(ctx context.Context, in *ListMemoCommentsRequest, opts ...grpc.CallOption) (*ListMemoCommentsResponse, error) ListMemoComments(ctx context.Context, in *ListMemoCommentsRequest, opts ...grpc.CallOption) (*ListMemoCommentsResponse, error)
} }
...@@ -160,16 +171,27 @@ func (c *memoServiceClient) ListMemoComments(ctx context.Context, in *ListMemoCo ...@@ -160,16 +171,27 @@ func (c *memoServiceClient) ListMemoComments(ctx context.Context, in *ListMemoCo
// All implementations must embed UnimplementedMemoServiceServer // All implementations must embed UnimplementedMemoServiceServer
// for forward compatibility // for forward compatibility
type MemoServiceServer interface { type MemoServiceServer interface {
// CreateMemo creates a memo.
CreateMemo(context.Context, *CreateMemoRequest) (*CreateMemoResponse, error) CreateMemo(context.Context, *CreateMemoRequest) (*CreateMemoResponse, error)
// ListMemos lists memos with pagination and filter.
ListMemos(context.Context, *ListMemosRequest) (*ListMemosResponse, error) ListMemos(context.Context, *ListMemosRequest) (*ListMemosResponse, error)
// GetMemo gets a memo by id.
GetMemo(context.Context, *GetMemoRequest) (*GetMemoResponse, error) GetMemo(context.Context, *GetMemoRequest) (*GetMemoResponse, error)
// UpdateMemo updates a memo.
UpdateMemo(context.Context, *UpdateMemoRequest) (*UpdateMemoResponse, error) UpdateMemo(context.Context, *UpdateMemoRequest) (*UpdateMemoResponse, error)
// DeleteMemo deletes a memo by id.
DeleteMemo(context.Context, *DeleteMemoRequest) (*DeleteMemoResponse, error) DeleteMemo(context.Context, *DeleteMemoRequest) (*DeleteMemoResponse, error)
// SetMemoResources sets resources for a memo.
SetMemoResources(context.Context, *SetMemoResourcesRequest) (*SetMemoResourcesResponse, error) SetMemoResources(context.Context, *SetMemoResourcesRequest) (*SetMemoResourcesResponse, error)
// ListMemoResources lists resources for a memo.
ListMemoResources(context.Context, *ListMemoResourcesRequest) (*ListMemoResourcesResponse, error) ListMemoResources(context.Context, *ListMemoResourcesRequest) (*ListMemoResourcesResponse, error)
// SetMemoRelations sets relations for a memo.
SetMemoRelations(context.Context, *SetMemoRelationsRequest) (*SetMemoRelationsResponse, error) SetMemoRelations(context.Context, *SetMemoRelationsRequest) (*SetMemoRelationsResponse, error)
// ListMemoRelations lists relations for a memo.
ListMemoRelations(context.Context, *ListMemoRelationsRequest) (*ListMemoRelationsResponse, error) ListMemoRelations(context.Context, *ListMemoRelationsRequest) (*ListMemoRelationsResponse, error)
// CreateMemoComment creates a comment for a memo.
CreateMemoComment(context.Context, *CreateMemoCommentRequest) (*CreateMemoCommentResponse, error) CreateMemoComment(context.Context, *CreateMemoCommentRequest) (*CreateMemoCommentResponse, error)
// ListMemoComments lists comments for a memo.
ListMemoComments(context.Context, *ListMemoCommentsRequest) (*ListMemoCommentsResponse, error) ListMemoComments(context.Context, *ListMemoCommentsRequest) (*ListMemoCommentsResponse, error)
mustEmbedUnimplementedMemoServiceServer() mustEmbedUnimplementedMemoServiceServer()
} }
......
This diff is collapsed.
import { Button } from "@mui/joy";
import copy from "copy-to-clipboard";
import React, { useEffect, useRef, useState } from "react";
import { toast } from "react-hot-toast";
import { getDateTimeString, getTimeString } from "@/helpers/datetime";
import useLoading from "@/hooks/useLoading";
import toImage from "@/labs/html2image";
import { useUserV1Store, extractUsernameFromName, useMemoV1Store } from "@/store/v1";
import { Memo } from "@/types/proto/api/v2/memo_service";
import { Resource } from "@/types/proto/api/v2/resource_service";
import { useTranslate } from "@/utils/i18n";
import { generateDialog } from "./Dialog";
import Icon from "./Icon";
import MemoContentV1 from "./MemoContentV1";
import MemoResourceListView from "./MemoResourceListView";
import UserAvatar from "./UserAvatar";
import "@/less/share-memo-dialog.less";
interface Props extends DialogProps {
memo: Memo;
}
const ShareMemoDialogV1: React.FC<Props> = (props: Props) => {
const { memo, destroy } = props;
const t = useTranslate();
const userV1Store = useUserV1Store();
const memoStore = useMemoV1Store();
const downloadingImageState = useLoading(false);
const loadingState = useLoading();
const memoElRef = useRef<HTMLDivElement>(null);
const [resources, setResources] = useState<Resource[]>([]);
const user = userV1Store.getUserByUsername(extractUsernameFromName(memo.creator));
useEffect(() => {
(async () => {
setResources(await memoStore.fetchMemoResources(memo.id));
await userV1Store.getOrFetchUserByUsername(extractUsernameFromName(memo.creator));
loadingState.setFinish();
})();
}, []);
const handleCloseBtnClick = () => {
destroy();
};
const handleDownloadImageBtnClick = () => {
if (!memoElRef.current) {
return;
}
downloadingImageState.setLoading();
toImage(memoElRef.current, {
pixelRatio: window.devicePixelRatio * 2,
})
.then((url) => {
const a = document.createElement("a");
a.href = url;
a.download = `memos-${getDateTimeString(Date.now())}.png`;
a.click();
downloadingImageState.setFinish();
})
.catch((err) => {
console.error(err);
});
};
const handleCopyLinkBtnClick = () => {
copy(`${window.location.origin}/m/${memo.id}`);
toast.success(t("message.succeed-copy-link"));
};
if (loadingState.isLoading) {
return null;
}
return (
<>
<div className="dialog-header-container py-3 px-4 !mb-0 rounded-t-lg">
<p className="">{t("common.share")} Memo</p>
<button className="btn close-btn" onClick={handleCloseBtnClick}>
<Icon.X className="icon-img" />
</button>
</div>
<div className="dialog-content-container w-full flex flex-col justify-start items-start relative">
<div className="px-4 pb-3 w-full flex flex-row justify-start items-center space-x-2">
<Button color="neutral" variant="outlined" disabled={downloadingImageState.isLoading} onClick={handleDownloadImageBtnClick}>
{downloadingImageState.isLoading ? (
<Icon.Loader className="w-4 h-auto mr-1 animate-spin" />
) : (
<Icon.Download className="w-4 h-auto mr-1" />
)}
{t("common.image")}
</Button>
<Button color="neutral" variant="outlined" onClick={handleCopyLinkBtnClick}>
<Icon.Link className="w-4 h-auto mr-1" />
{t("common.link")}
</Button>
</div>
<div className="w-full border-t dark:border-zinc-700 overflow-clip">
<div
className="w-full h-auto select-none relative flex flex-col justify-start items-start bg-white dark:bg-zinc-800"
ref={memoElRef}
>
<span className="w-full px-6 pt-5 pb-2 text-sm text-gray-500">{getTimeString(memo.displayTime)}</span>
<div className="w-full px-6 text-base pb-4">
<MemoContentV1 content={memo.content} />
<MemoResourceListView resourceList={resources} />
</div>
<div className="flex flex-row justify-between items-center w-full bg-gray-100 dark:bg-zinc-700 py-4 px-6">
<div className="flex flex-row justify-start items-center">
<UserAvatar className="mr-2" avatarUrl={user.avatarUrl} />
<div className="w-auto grow truncate flex mr-2 flex-col justify-center items-start">
<span className="w-full text truncate font-medium text-gray-600 dark:text-gray-300">
{user.nickname || extractUsernameFromName(user.name)}
</span>
</div>
</div>
<span className="text-gray-500 dark:text-gray-400">via memos</span>
</div>
</div>
</div>
</div>
</>
);
};
export default function showShareMemoDialogV1(memo: Memo): void {
generateDialog(
{
className: "share-memo-dialog-v1",
dialogName: "share-memo-dialog-v1",
},
ShareMemoDialogV1,
{ memo }
);
}
...@@ -44,7 +44,7 @@ const Archived = () => { ...@@ -44,7 +44,7 @@ const Archived = () => {
style: "danger", style: "danger",
dialogName: "delete-memo-dialog", dialogName: "delete-memo-dialog",
onConfirm: async () => { onConfirm: async () => {
await memoStore.deleteMemo(memo); await memoStore.deleteMemo(memo.id);
setArchivedMemos((prev) => prev.filter((m) => m.id !== memo.id)); setArchivedMemos((prev) => prev.filter((m) => m.id !== memo.id));
}, },
}); });
......
This diff is collapsed.
...@@ -62,12 +62,12 @@ export const useMemoV1Store = create( ...@@ -62,12 +62,12 @@ export const useMemoV1Store = create(
return memo; return memo;
}, },
deleteMemo: async (memo: Memo) => { deleteMemo: async (id: number) => {
await memoServiceClient.deleteMemo({ await memoServiceClient.deleteMemo({
id: memo.id, id: id,
}); });
set((state) => { set((state) => {
state.memoById.delete(memo.id); state.memoById.delete(id);
return state; return state;
}); });
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment