Skip to content

Commit

Permalink
adding tabs for gallery and grid views
Browse files Browse the repository at this point in the history
  • Loading branch information
webdevcody committed Feb 2, 2024
1 parent 1ffc8af commit 331a6f3
Show file tree
Hide file tree
Showing 10 changed files with 507 additions and 54 deletions.
2 changes: 2 additions & 0 deletions convex/_generated/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type * as stripe from "../stripe.js";
import type * as thumbnails from "../thumbnails.js";
import type * as users from "../users.js";
import type * as util from "../util.js";
import type * as vision from "../vision.js";

/**
* A utility for referencing Convex functions in your app's API.
Expand All @@ -40,6 +41,7 @@ declare const fullApi: ApiFromModules<{
thumbnails: typeof thumbnails;
users: typeof users;
util: typeof util;
vision: typeof vision;
}>;
export declare const api: FilterApi<
typeof fullApi,
Expand Down
74 changes: 67 additions & 7 deletions convex/thumbnails.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,59 @@
import { ConvexError, v } from "convex/values";
import { query } from "./_generated/server";
import { action, internalMutation, query } from "./_generated/server";
import { paginationOptsValidator } from "convex/server";
import { adminAuthMutation, authMutation, authQuery } from "./util";
import { adminAuthMutation, authAction, authMutation, authQuery } from "./util";
import { internal } from "./_generated/api";
import { Id } from "./_generated/dataModel";

export const createThumbnail = authMutation({
export const createThumbnail = internalMutation({
args: {
title: v.string(),
images: v.array(v.string()),
userId: v.id("users"),
},
handler: async (ctx, args) => {
return await ctx.db.insert("thumbnails", {
const user = await ctx.db.get(args.userId);

if (!user) {
throw new ConvexError("User not found");
}

const id = await ctx.db.insert("thumbnails", {
title: args.title,
userId: ctx.user._id,
userId: user._id,
images: args.images,
votes: args.images.map(() => 0),
voteIds: [],
profileImage: ctx.user.profileImage,
name: ctx.user.name,
profileImage: user.profileImage,
name: user.name,
});

return id;
},
});

export const createThumbnailAction = authAction({
args: {
title: v.string(),
images: v.array(v.id("_storage")),
},
handler: async (ctx, args) => {
const thumbnailId: Id<"thumbnails"> = await ctx.runMutation(
internal.thumbnails.createThumbnail,
{
images: args.images,
title: args.title,
userId: ctx.user._id,
}
);

await ctx.scheduler.runAfter(0, internal.vision.generateAIComment, {
imageIds: args.images,
thumbnailId: thumbnailId,
userId: ctx.user._id,
});

return thumbnailId;
},
});

Expand Down Expand Up @@ -53,6 +89,30 @@ export const addComment = authMutation({
},
});

export const addCommentInternal = internalMutation({
args: {
thumbnailId: v.id("thumbnails"),
text: v.string(),
userId: v.id("users"),
},
handler: async (ctx, args) => {
const thumbnail = await ctx.db.get(args.thumbnailId);

if (!thumbnail) {
throw new Error("thumbnail by id did not exist");
}

await ctx.db.insert("comments", {
createdAt: Date.now(),
text: args.text,
userId: args.userId,
thumbnailId: args.thumbnailId,
name: "GPT4 Vision",
profileUrl: "",
});
},
});

export const getThumbnail = query({
args: { thumbnailId: v.id("thumbnails") },
handler: async (ctx, args) => {
Expand Down
13 changes: 13 additions & 0 deletions convex/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
MutationCtx,
QueryCtx,
internalMutation,
internalQuery,
query,
} from "./_generated/server";
import { authMutation, authQuery } from "./util";
Expand All @@ -16,6 +17,18 @@ export const getUser = authQuery({
},
});

export const getUserById = internalQuery({
args: { userId: v.string() },
handler: async (ctx, args) => {
const user = await ctx.db
.query("users")
.withIndex("by_userId", (q) => q.eq("userId", args.userId))
.first();

return user;
},
});

export const getProfile = query({
args: { userId: v.id("users") },
handler: async (ctx, args) => {
Expand Down
24 changes: 24 additions & 0 deletions convex/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ import {
ActionCtx,
MutationCtx,
QueryCtx,
action,
mutation,
} from "./_generated/server";
import {
customQuery,
customCtx,
customMutation,
customAction,
} from "convex-helpers/server/customFunctions";
import { query } from "./_generated/server";
import { ConvexError } from "convex/values";
import { internal } from "./_generated/api";

export const authQuery = customQuery(
query,
Expand All @@ -23,6 +26,27 @@ export const authQuery = customQuery(
})
);

export const authAction = customAction(
action,
customCtx(async (ctx) => {
const userId = (await ctx.auth.getUserIdentity())?.subject;

if (!userId) {
throw new ConvexError("must be logged in");
}

const user: any = await ctx.runQuery(internal.users.getUserById, {
userId,
});

if (!user) {
throw new ConvexError("user not found");
}

return { user };
})
);

export const authMutation = customMutation(
mutation,
customCtx(async (ctx) => ({ user: await getUserOrThrow(ctx) }))
Expand Down
49 changes: 49 additions & 0 deletions convex/vision.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import OpenAI from "openai";
import { internalAction } from "./_generated/server";
import { v } from "convex/values";
import { api, internal } from "./_generated/api";

const openai = new OpenAI();

export const generateAIComment = internalAction({
args: {
imageIds: v.array(v.id("_storage")),
thumbnailId: v.id("thumbnails"),
userId: v.id("users"),
},
async handler(ctx, args) {
const images = await Promise.all(
args.imageIds.map(async (imageId) => ({
type: "image_url",
image_url: {
url: await ctx.storage.getUrl(imageId),
},
}))
);

const response = await openai.chat.completions.create({
model: "gpt-4-vision-preview",
max_tokens: 1000,
messages: [
{
role: "user",
content: [
{
type: "text",
text: "Pick which Thumbnails Looks the Best:",
},
...(images as any),
],
},
],
});

const content = response.choices[0].message.content;

await ctx.runMutation(internal.thumbnails.addCommentInternal, {
thumbnailId: args.thumbnailId,
text: content ?? "",
userId: args.userId,
});
},
});
Loading

0 comments on commit 331a6f3

Please sign in to comment.