Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web-ui): post and reaction notification links #317

Merged
merged 5 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/domain/reaction/aggregate/feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default async function feature(requester: Requester, data: DataModel): Pr
createdAt: data.createdAt,
ratingCount: data.ratingCount,
creator: relationData,
postId: data.postId,
hasRated,
comic: comicData,
comment: commentData,
Expand Down
2 changes: 1 addition & 1 deletion src/domain/reaction/aggregate/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { AggregatedData as RelationData } from '^/domain/relation/aggregate

import type { DataModel } from '../types';

type AggregatedData = Pick<DataModel, 'id' | 'createdAt' | 'ratingCount'> &
type AggregatedData = Pick<DataModel, 'id' | 'createdAt' | 'ratingCount' | 'postId'> &
{
readonly creator: RelationData;
readonly hasRated: boolean;
Expand Down
2 changes: 1 addition & 1 deletion src/domain/reaction/create/feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default async function feature(creatorId: string, postId: string, comicId

const post = await retrievePost(postId);

await createNotification(Types.ADDED_REACTION, creatorId, post.creatorId, postId);
await createNotification(Types.ADDED_REACTION, creatorId, post.creatorId, postId, id);

return id;
}
Expand Down
2 changes: 2 additions & 0 deletions src/webui/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import NotFound from './features/NotFound';
import Notifications from './features/Notifications';
import PostDetails from './features/PostDetails';
import Profile from './features/Profile';
import ReactionDetails from './features/ReactionDetails';
import Timeline from './features/Timeline';

export default function Component()
Expand All @@ -38,6 +39,7 @@ export default function Component()
<Route path="/profile/:nickname/:tab?" element={protect(<Profile />)} />
<Route path="/edit/profile" element={protect(<EditProfile />)} />
<Route path="/post/:postId" element={protect(<PostDetails />)} />
<Route path="/post/:postId/reaction/:reactionId" element={protect(<ReactionDetails />)} />
<Route path="/logout" element={protect(<Logout />)} />

<Route path="*" element={<NotFound />} />
Expand Down
2 changes: 2 additions & 0 deletions src/webui/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export { default as NotificationPanelList } from './notification/PanelList';
export { default as PostDetailsPanel } from './post/DetailsPanel';
export { default as PostPanelGrid } from './post/PanelGrid';
export { default as PostPanelList } from './post/PanelList';
export { default as ReactionLargePanel } from './reaction/LargePanel';
export { default as ReactionPanelList } from './reaction/PanelList';
export { default as SingleReactionRow } from './reaction/SingleReactionRow';
export { default as RelationPanelList } from './relation/PanelList';
export { default as RelationProfile } from './relation/Profile';

15 changes: 8 additions & 7 deletions src/webui/components/notification/Panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,22 @@ type Props = {
readonly notification: NotificationView;
readonly onFollowClick: (relation: RelationView) => Promise<void>;
readonly onCreatorClick: (relation: RelationView) => void;
readonly onComicClick: (post: PostView) => void;
readonly onReactionClick: (reaction: ReactionView) => void;
readonly onPostClick: (post: PostView) => void;
};

function getContent(notification: NotificationView, onComicClick: (post: PostView) => void)
function getContent(notification: NotificationView, onReactionClick: (reaction: ReactionView) => void, onPostClick: (post: PostView) => void)
{
switch (notification.type)
{
case 'started-following': return <StartedFollowing isFollowing={notification.relation.established} />;
case 'rated-post': return <RatedPost comicDataUrl={notification.post?.comic.image.dataUrl as string} />;
case 'rated-reaction': return <RatedReaction reaction={notification.reaction as ReactionView} />;
case 'added-reaction': return <AddedReaction post={notification.post as PostView} onComicClick={onComicClick} />;
case 'rated-post': return <RatedPost post={notification.post as PostView} onPostClick={onPostClick} />;
case 'rated-reaction': return <RatedReaction reaction={notification.reaction as ReactionView} onReactionClick={onReactionClick} />;
case 'added-reaction': return <AddedReaction notification={notification} onReactionClick={onReactionClick} />;
}
}

export default function Component({ notification, onFollowClick, onCreatorClick, onComicClick }: Props)
export default function Component({ notification, onFollowClick, onCreatorClick, onReactionClick, onPostClick }: Props)
{
return <Panel>
<Column gap='medium' alignX='stretch'>
Expand All @@ -40,7 +41,7 @@ export default function Component({ notification, onFollowClick, onCreatorClick,
onFollowClick={onFollowClick}
onCreatorClick={onCreatorClick}
/>
{getContent(notification, onComicClick)}
{getContent(notification, onReactionClick, onPostClick)}
</Column>
</Panel>;
}
9 changes: 6 additions & 3 deletions src/webui/components/notification/PanelList.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

import type { AggregatedData as NotificationView } from '^/domain/notification/aggregate/types';
import type { AggregatedData as PostView } from '^/domain/post/aggregate/types';
import type { AggregatedData as ReactionView } from '^/domain/reaction/aggregate/types';
import type { AggregatedData as RelationView } from '^/domain/relation/aggregate/types';

import { Column } from '^/webui/designsystem';
Expand All @@ -11,10 +12,11 @@ type Props = {
readonly notifications: NotificationView[];
readonly onFollowClick: (relation: RelationView) => Promise<void>;
readonly onCreatorClick: (relation: RelationView) => void;
readonly onComicClick: (post: PostView) => void;
readonly onReactionClick: (reaction: ReactionView) => void;
readonly onPostClick: (post: PostView) => void;
};

export default function Component({ notifications, onFollowClick, onCreatorClick, onComicClick }: Props)
export default function Component({ notifications, onFollowClick, onCreatorClick, onReactionClick, onPostClick }: Props)
{
return <Column gap='medium' alignX='stretch'>
{
Expand All @@ -24,7 +26,8 @@ export default function Component({ notifications, onFollowClick, onCreatorClick
notification={notification}
onFollowClick={onFollowClick}
onCreatorClick={onCreatorClick}
onComicClick={onComicClick}
onReactionClick={onReactionClick}
onPostClick={onPostClick}
/>
)
}
Expand Down
13 changes: 7 additions & 6 deletions src/webui/components/notification/elementary/AddedReaction.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@

import type { AggregatedData as PostView } from '^/domain/post/aggregate/types';
import type { AggregatedData as NotificationView } from '^/domain/notification/aggregate/types';
import type { AggregatedData as ReactionView } from '^/domain/reaction/aggregate/types';
import { ClickArea, Image, Row, Text } from '^/webui/designsystem';

type Props = {
readonly post: PostView;
readonly onComicClick: (post: PostView) => void;
readonly notification: NotificationView;
readonly onReactionClick: (reaction: ReactionView) => void;
};

export default function Component({ post, onComicClick }: Props)
export default function Component({ notification, onReactionClick }: Props)
{
return <Row alignX='justify' alignY='stretch' gap='medium'>
<Text value='I added a reaction to your post.' />
<ClickArea onClick={() => onComicClick(post)}>
<Image source={post.comic.image.dataUrl} width='150px' />
<ClickArea onClick={() => onReactionClick(notification.reaction as ReactionView)}>
<Image source={notification.post?.comic.image.dataUrl as string} width='150px' />
</ClickArea>
</Row>;
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@

import { Image, Row, Text } from '^/webui/designsystem';
import { ClickArea, Image, Row, Text } from '^/webui/designsystem';

import type { AggregatedData as ReactionView } from '^/domain/reaction/aggregate/types';

type Props = {
readonly comicDataUrl: string;
readonly reaction: ReactionView;
readonly onReactionClick: (reaction: ReactionView) => void;
};

export default function Component({ comicDataUrl }: Props)
export default function Component({ reaction, onReactionClick }: Props)
{
return <Row alignX='justify' alignY='stretch' gap='medium'>
<Text value='I like your reaction.' />
<Image source={comicDataUrl} width='150px' />
<ClickArea onClick={() => onReactionClick(reaction)} >
<Image source={reaction.comic?.image.dataUrl as string} width='150px' />
</ClickArea>
</Row>;
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@

import { Border, Column, Text } from '^/webui/designsystem';
import { Border, ClickArea, Column, Text } from '^/webui/designsystem';

import type { AggregatedData as ReactionView } from '^/domain/reaction/aggregate/types';

type Props = {
readonly comment: string;
readonly reaction: ReactionView;
readonly onReactionClick: (reaction: ReactionView) => void;
};

export default function Component({ comment }: Props)
export default function Component({ reaction, onReactionClick }: Props)
{

return <Column alignX='stretch' alignY='justify' gap='medium'>
<Text value='I like your reaction.' />
<Border size='small' padding='small'>
<Text size='small' wrap='normal' value={comment} />
</Border>
<ClickArea onClick={() => onReactionClick(reaction)} >
<Border size='small' padding='small'>
<Text size='small' wrap='normal' value={reaction.comment?.message as string} />
</Border>
</ClickArea>
</Column>;
}
13 changes: 9 additions & 4 deletions src/webui/components/notification/elementary/RatedPost.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@

import { Image, Row, Text } from '^/webui/designsystem';
import { ClickArea, Image, Row, Text } from '^/webui/designsystem';

import type { AggregatedData as PostView } from '^/domain/post/aggregate/types';

type Props = {
readonly comicDataUrl: string;
readonly post: PostView;
readonly onPostClick: (post: PostView) => void;
};

export default function Component({ comicDataUrl }: Props)
export default function Component({ post, onPostClick }: Props)
{
return <Row gap='medium' alignX='justify'>
<Text value='I like your comic.' />
<Image source={comicDataUrl} width='150px' />
<ClickArea onClick={() => onPostClick(post)} >
<Image source={post.comic.image.dataUrl} width='150px' />
</ClickArea>
</Row>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import RatedCommentReaction from '../elementary/RatedCommentReaction';

type Props = {
readonly reaction: ReactionView;
readonly onReactionClick: (reaction: ReactionView) => void;
};

export default function Component({ reaction }: Props)
export default function Component({ reaction, onReactionClick }: Props)
{
return reaction.comic !== undefined
? <RatedComicReaction comicDataUrl={reaction.comic.image.dataUrl} />
: <RatedCommentReaction comment={reaction.comment?.message as string} />;
? <RatedComicReaction reaction={reaction} onReactionClick={onReactionClick} />
: <RatedCommentReaction reaction={reaction} onReactionClick={onReactionClick} />;
}
2 changes: 1 addition & 1 deletion src/webui/components/reaction/LargePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type Props = {
readonly onDeleteClick: (relation: ReactionView) => Promise<void>;
};

export default function LargePanel({ reaction, onFollowClick, onCreatorClick, onRatingClick, onDeleteClick }: Props)
export default function Component({ reaction, onFollowClick, onCreatorClick, onRatingClick, onDeleteClick }: Props)
{
return <Panel padding='medium'>
<Column gap='medium' alignX='stretch'>
Expand Down
16 changes: 16 additions & 0 deletions src/webui/components/reaction/SingleReactionRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

import { ClickArea, Row, Text } from '^/webui/designsystem';

type Props = {
readonly onShowClick: () => void;
};

export default function Component({ onShowClick }: Props)
{
return <Row alignY='stretch' alignX='justify' >
<Text value='single reaction' />
<ClickArea onClick={onShowClick}>
<Text value='all reactions' />
</ClickArea>
</Row>;
}
5 changes: 4 additions & 1 deletion src/webui/features/Notifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import useEstablishRelation from './hooks/useEstablishRelation';
import useNotifications from './hooks/useNotifications';
import useViewPostDetails from './hooks/useViewPostDetails';
import useViewProfile from './hooks/useViewProfile';
import useViewReactionDetails from './hooks/useViewReactionDetails';

const SCROLL_THRESHOLD = 0.7;

export default function Feature()
{
const establishRelation = useEstablishRelation();
const viewProfile = useViewProfile();
const viewReactionDetails = useViewReactionDetails();
const viewPostDetails = useViewPostDetails();

const [notifications, isLoading, isFinished, getMoreNotifications, , refresh] = useNotifications();
Expand All @@ -27,7 +29,8 @@ export default function Feature()
notifications={notifications as NotificationView[]}
onFollowClick={establishRelation}
onCreatorClick={viewProfile}
onComicClick={viewPostDetails}
onReactionClick={viewReactionDetails}
onPostClick={viewPostDetails}
/>
</ResultSet>
</ScrollLoader>
Expand Down
Loading