mirror of
https://github.com/ahmadk953/tasko.git
synced 2025-01-31 00:53:37 +00:00
Started Adding Liveblocks
This commit is contained in:
parent
cde7e7ab6e
commit
03dd8df0f1
4 changed files with 248 additions and 3 deletions
26
app/api/liveblocks-auth/route.ts
Normal file
26
app/api/liveblocks-auth/route.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { Liveblocks } from '@liveblocks/node';
|
||||
import { useUser, auth } from '@clerk/nextjs';
|
||||
|
||||
const liveblocks = new Liveblocks({
|
||||
secret: process.env.LIVEBLOCKS_SECRET_DEV_API_KEY!,
|
||||
});
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const { user } = useUser();
|
||||
const { orgId } = auth();
|
||||
|
||||
if (!orgId || !user) return new Response('Unauthorized', { status: 401 });
|
||||
|
||||
// Start an auth session inside your endpoint
|
||||
const session = liveblocks.prepareSession(user.id);
|
||||
|
||||
// Implement your own security, and give the user access to the room
|
||||
const { room } = await req.json();
|
||||
if (room) {
|
||||
session.allow(room, session.FULL_ACCESS);
|
||||
}
|
||||
|
||||
// Authorize the user and return the result
|
||||
const { status, body } = await session.authorize();
|
||||
return new Response(body, { status });
|
||||
}
|
127
liveblocks.config.ts
Normal file
127
liveblocks.config.ts
Normal file
|
@ -0,0 +1,127 @@
|
|||
import { createClient } from '@liveblocks/client';
|
||||
import { createRoomContext } from '@liveblocks/react';
|
||||
|
||||
const client = createClient({
|
||||
// publicApiKey: process.env.LIVEBLOCKS_PUBLIC_DEV_API_KEY!,
|
||||
authEndpoint: '/api/liveblocks-auth',
|
||||
// throttle: 100,
|
||||
});
|
||||
|
||||
// Presence represents the properties that exist on every user in the Room
|
||||
// and that will automatically be kept in sync. Accessible through the
|
||||
// `user.presence` property. Must be JSON-serializable.
|
||||
type Presence = {
|
||||
// cursor: { x: number, y: number } | null,
|
||||
// ...
|
||||
};
|
||||
|
||||
// Optionally, Storage represents the shared document that persists in the
|
||||
// Room, even after all users leave. Fields under Storage typically are
|
||||
// LiveList, LiveMap, LiveObject instances, for which updates are
|
||||
// automatically persisted and synced to all connected clients.
|
||||
type Storage = {
|
||||
// author: LiveObject<{ firstName: string, lastName: string }>,
|
||||
// ...
|
||||
};
|
||||
|
||||
// Optionally, UserMeta represents static/readonly metadata on each user, as
|
||||
// provided by your own custom auth back end (if used). Useful for data that
|
||||
// will not change during a session, like a user's name or avatar.
|
||||
type UserMeta = {
|
||||
id?: string; // Accessible through `user.id`
|
||||
// info?: Json, // Accessible through `user.info`
|
||||
};
|
||||
|
||||
// Optionally, the type of custom events broadcast and listened to in this
|
||||
// room. Use a union for multiple events. Must be JSON-serializable.
|
||||
type RoomEvent = {
|
||||
// type: "NOTIFICATION",
|
||||
// ...
|
||||
};
|
||||
|
||||
// Optionally, when using Comments, ThreadMetadata represents metadata on
|
||||
// each thread. Can only contain booleans, strings, and numbers.
|
||||
export type ThreadMetadata = {
|
||||
// resolved: boolean;
|
||||
// quote: string;
|
||||
// time: number;
|
||||
};
|
||||
|
||||
export const {
|
||||
suspense: {
|
||||
RoomProvider,
|
||||
useRoom,
|
||||
useMyPresence,
|
||||
useUpdateMyPresence,
|
||||
useSelf,
|
||||
useOthers,
|
||||
useOthersMapped,
|
||||
useOthersConnectionIds,
|
||||
useOther,
|
||||
useBroadcastEvent,
|
||||
useEventListener,
|
||||
useErrorListener,
|
||||
useStorage,
|
||||
useObject,
|
||||
useMap,
|
||||
useList,
|
||||
useBatch,
|
||||
useHistory,
|
||||
useUndo,
|
||||
useRedo,
|
||||
useCanUndo,
|
||||
useCanRedo,
|
||||
useMutation,
|
||||
useStatus,
|
||||
useLostConnectionListener,
|
||||
useThreads,
|
||||
useUser,
|
||||
useCreateThread,
|
||||
useEditThreadMetadata,
|
||||
useCreateComment,
|
||||
useEditComment,
|
||||
useDeleteComment,
|
||||
useAddReaction,
|
||||
useRemoveReaction,
|
||||
},
|
||||
} = createRoomContext<Presence, Storage, UserMeta, RoomEvent, ThreadMetadata>(
|
||||
client,
|
||||
{
|
||||
async resolveUsers({ userIds }) {
|
||||
// Used only for Comments. Return a list of user information retrieved
|
||||
// from `userIds`. This info is used in comments, mentions etc.
|
||||
|
||||
// const usersData = await __fetchUsersFromDB__(userIds);
|
||||
//
|
||||
// return usersData.map((userData) => ({
|
||||
// name: userData.name,
|
||||
// avatar: userData.avatar.src,
|
||||
// }));
|
||||
|
||||
return [];
|
||||
},
|
||||
async resolveMentionSuggestions({ text, roomId }) {
|
||||
// Used only for Comments. Return a list of userIds that match `text`.
|
||||
// These userIds are used to create a mention list when typing in the
|
||||
// composer.
|
||||
//
|
||||
// For example when you type "@jo", `text` will be `"jo"`, and
|
||||
// you should to return an array with John and Joanna's userIds:
|
||||
// ["john@example.com", "joanna@example.com"]
|
||||
|
||||
// const userIds = await __fetchAllUserIdsFromDB__(roomId);
|
||||
//
|
||||
// Return all userIds if no `text`
|
||||
// if (!text) {
|
||||
// return userIds;
|
||||
// }
|
||||
//
|
||||
// Otherwise, filter userIds for the search `text` and return
|
||||
// return userIds.filter((userId) =>
|
||||
// userId.toLowerCase().includes(text.toLowerCase())
|
||||
// );
|
||||
|
||||
return [];
|
||||
},
|
||||
}
|
||||
);
|
89
package-lock.json
generated
89
package-lock.json
generated
|
@ -11,6 +11,9 @@
|
|||
"dependencies": {
|
||||
"@clerk/nextjs": "^4.29.3",
|
||||
"@hello-pangea/dnd": "^16.5.0",
|
||||
"@liveblocks/client": "^1.9.8",
|
||||
"@liveblocks/node": "^1.9.8",
|
||||
"@liveblocks/react": "^1.9.8",
|
||||
"@prisma/client": "^5.9.1",
|
||||
"@radix-ui/react-accordion": "^1.1.2",
|
||||
"@radix-ui/react-avatar": "^1.0.4",
|
||||
|
@ -480,6 +483,44 @@
|
|||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@liveblocks/client": {
|
||||
"version": "1.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@liveblocks/client/-/client-1.9.8.tgz",
|
||||
"integrity": "sha512-qNFHMKOLLPNlo0HaVL7jfh877PngWYIxuZrpfnFdttR/NtDlt1gH9cL/xoyV5roULf6a5tONcMt2NqJXAFkVEw==",
|
||||
"dependencies": {
|
||||
"@liveblocks/core": "1.9.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@liveblocks/core": {
|
||||
"version": "1.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@liveblocks/core/-/core-1.9.8.tgz",
|
||||
"integrity": "sha512-sIt/pqQzdMSePYxT/9YAhsR8KKDSGDo9uO8S4LJKp7wR2AgzjfXJfEFMXUe2W3D+ugzo5RZODccJS6OdgGzEnQ=="
|
||||
},
|
||||
"node_modules/@liveblocks/node": {
|
||||
"version": "1.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@liveblocks/node/-/node-1.9.8.tgz",
|
||||
"integrity": "sha512-bK88vp0k3P9UngomiZjqhsiyUWKbyUvHmqeCgeSSksu1pjoivVDFu22WJrJRQws4g7+DdfCXN7kzQMD5QKVSzg==",
|
||||
"dependencies": {
|
||||
"@liveblocks/core": "1.9.8",
|
||||
"@stablelib/base64": "^1.0.1",
|
||||
"fast-sha256": "^1.3.0",
|
||||
"node-fetch": "^2.6.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@liveblocks/react": {
|
||||
"version": "1.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@liveblocks/react/-/react-1.9.8.tgz",
|
||||
"integrity": "sha512-8ZXHeG8StX5g/YZ5LYejgHBPC5WAQX8vqxshsT0kVyvP+vZCId0FCA/74uAp5DTzP0UVyQ28mINWsHqVC7t/9w==",
|
||||
"dependencies": {
|
||||
"@liveblocks/client": "1.9.8",
|
||||
"@liveblocks/core": "1.9.8",
|
||||
"nanoid": "^3",
|
||||
"use-sync-external-store": "^1.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.14.0 || ^17 || ^18"
|
||||
}
|
||||
},
|
||||
"node_modules/@next/env": {
|
||||
"version": "14.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.0.4.tgz",
|
||||
|
@ -1471,6 +1512,11 @@
|
|||
"integrity": "sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@stablelib/base64": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/base64/-/base64-1.0.1.tgz",
|
||||
"integrity": "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ=="
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz",
|
||||
|
@ -3555,6 +3601,11 @@
|
|||
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fast-sha256": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz",
|
||||
"integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ=="
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
|
||||
|
@ -4823,6 +4874,25 @@
|
|||
"tslib": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch-native": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.0.1.tgz",
|
||||
|
@ -6403,6 +6473,11 @@
|
|||
"to-no-case": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/ts-api-utils": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz",
|
||||
|
@ -6711,6 +6786,20 @@
|
|||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
"dependencies": {
|
||||
"@clerk/nextjs": "^4.29.3",
|
||||
"@hello-pangea/dnd": "^16.5.0",
|
||||
"@liveblocks/client": "^1.9.8",
|
||||
"@liveblocks/node": "^1.9.8",
|
||||
"@liveblocks/react": "^1.9.8",
|
||||
"@prisma/client": "^5.9.1",
|
||||
"@radix-ui/react-accordion": "^1.1.2",
|
||||
"@radix-ui/react-avatar": "^1.0.4",
|
||||
|
@ -42,20 +45,20 @@
|
|||
"zustand": "^4.4.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/eslint-plugin-next": "^14.1.0",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"@next/eslint-plugin-next": "^14.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
||||
"@typescript-eslint/parser": "^7.0.0",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-next": "^14.1.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"postcss": "^8",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-tailwindcss": "^0.5.11",
|
||||
"postcss": "^8",
|
||||
"prisma": "^5.9.1",
|
||||
"tailwindcss": "^3.3.0",
|
||||
"typescript": "^5"
|
||||
|
|
Loading…
Reference in a new issue