Added timestamps to tweets and they organize by newest on top

This commit is contained in:
2026-04-01 11:58:12 -04:00
parent ae35600822
commit 0ac0b68029
5 changed files with 193 additions and 7 deletions

View File

@@ -4,6 +4,7 @@
export type UUID = string;
export type UtcDateTimeUsec = string;
// media Schema
export type mediaResourceSchema = {
@@ -31,13 +32,15 @@ export type mediaAttributesOnlySchema = {
// tweets Schema
export type tweetsResourceSchema = {
__type: "Resource";
__primitiveFields: "id" | "content" | "likes" | "userId" | "state" | "likedByMe";
__primitiveFields: "id" | "content" | "likes" | "userId" | "insertedAt" | "state" | "likedByMe" | "userEmail";
id: UUID;
content: string;
likes: number;
userId: UUID;
insertedAt: UtcDateTimeUsec;
state: "posted" | "drafted";
likedByMe: boolean;
userEmail: string | null;
media: { __type: "Relationship"; __array: true; __resource: mediaResourceSchema; };
};
@@ -45,11 +48,12 @@ export type tweetsResourceSchema = {
export type tweetsAttributesOnlySchema = {
__type: "Resource";
__primitiveFields: "id" | "content" | "likes" | "userId" | "state";
__primitiveFields: "id" | "content" | "likes" | "userId" | "insertedAt" | "state";
id: UUID;
content: string;
likes: number;
userId: UUID;
insertedAt: UtcDateTimeUsec;
state: "posted" | "drafted";
};
@@ -121,12 +125,29 @@ export type tweetsFilterInput = {
in?: Array<UUID>;
};
insertedAt?: {
eq?: UtcDateTimeUsec;
notEq?: UtcDateTimeUsec;
greaterThan?: UtcDateTimeUsec;
greaterThanOrEqual?: UtcDateTimeUsec;
lessThan?: UtcDateTimeUsec;
lessThanOrEqual?: UtcDateTimeUsec;
in?: Array<UtcDateTimeUsec>;
};
state?: {
eq?: "posted" | "drafted";
notEq?: "posted" | "drafted";
in?: Array<"posted" | "drafted">;
};
userEmail?: {
eq?: string;
notEq?: string;
in?: Array<string>;
isNil?: boolean;
};
likedByMe?: {
eq?: boolean;
notEq?: boolean;
@@ -141,14 +162,14 @@ export type tweetsFilterInput = {
export const mediaFilterFields = ["id", "s3Key", "userId", "tweetId", "user", "tweet"] as const;
export type mediaFilterField = (typeof mediaFilterFields)[number];
export const tweetsFilterFields = ["id", "content", "likes", "userId", "state", "likedByMe", "user", "media"] as const;
export const tweetsFilterFields = ["id", "content", "likes", "userId", "insertedAt", "state", "userEmail", "likedByMe", "user", "media"] as const;
export type tweetsFilterField = (typeof tweetsFilterFields)[number];
export const mediaSortFields = ["id", "s3Key", "userId", "tweetId"] as const;
export type mediaSortField = (typeof mediaSortFields)[number];
export const tweetsSortFields = ["id", "content", "likes", "userId", "state", "likedByMe"] as const;
export const tweetsSortFields = ["id", "content", "likes", "userId", "insertedAt", "state", "userEmail", "likedByMe"] as const;
export type tweetsSortField = (typeof tweetsSortFields)[number];

View File

@@ -33,6 +33,8 @@ type Tweet = {
userId: string;
state: string;
media?: MediaItem[];
userEmail?: string | null;
insertedAt?: string | null;
};
// ── Auth context ───────────────────────────────────────────────────────────────
@@ -376,7 +378,7 @@ function TweetCard({ tweet }: { tweet: Tweet }) {
</div>
<div className="mx-tweet-body">
<div className="mx-tweet-header">
<span className="mx-tweet-handle">@mixer</span>
<span className="mx-tweet-handle">{tweet.userEmail ?? "@mixer"}</span>
<span className="mx-tweet-dot">·</span>
<span className="mx-tweet-time">{timeAgo()}</span>
{canModify && (
@@ -490,8 +492,8 @@ function Feed() {
queryKey: ["tweets"],
queryFn: async () => {
const res = await readTweet({
fields: ["id", "content", "likes", "likedByMe", "userId", "state", { media: ["id", "s3Key"] }],
sort: "-id",
fields: ["id", "content", "likes", "likedByMe", "userId", "state", "userEmail", "insertedAt", { media: ["id", "s3Key"] }],
sort: "-insertedAt",
headers: buildCSRFHeaders(),
});
if (!res.success) throw new Error("Failed to load tweets");