feat: add TypeScript type checking task to VSCode configuration
feat: implement area metadata blocks in game commands for enhanced area details fix: refactor game commands to utilize new area metadata blocks and improve code consistency feat: enhance Appwrite API integration with additional collections and storage support refactor: update componentsV2 to support image blocks in display rendering
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// Simple Appwrite client wrapper
|
||||
// @ts-ignore
|
||||
import { Client, Databases } from "node-appwrite";
|
||||
import { Client, Databases, Storage } from "node-appwrite";
|
||||
|
||||
const endpoint = process.env.APPWRITE_ENDPOINT || "";
|
||||
const projectId = process.env.APPWRITE_PROJECT_ID || "";
|
||||
@@ -14,8 +14,21 @@ export const APPWRITE_COLLECTION_AI_CONVERSATIONS_ID =
|
||||
export const APPWRITE_COLLECTION_GUILD_CACHE_ID =
|
||||
process.env.APPWRITE_COLLECTION_GUILD_CACHE_ID || "";
|
||||
|
||||
// Optional: collections for game realtime mirrors
|
||||
export const APPWRITE_COLLECTION_QUESTS_ID =
|
||||
process.env.APPWRITE_COLLECTION_QUESTS_ID || "";
|
||||
export const APPWRITE_COLLECTION_QUEST_PROGRESS_ID =
|
||||
process.env.APPWRITE_COLLECTION_QUEST_PROGRESS_ID || "";
|
||||
export const APPWRITE_COLLECTION_SCHEDULED_ATTACKS_ID =
|
||||
process.env.APPWRITE_COLLECTION_SCHEDULED_ATTACKS_ID || "";
|
||||
|
||||
// Optional: bucket for images (areas/levels)
|
||||
export const APPWRITE_BUCKET_IMAGES_ID =
|
||||
process.env.APPWRITE_BUCKET_IMAGES_ID || "";
|
||||
|
||||
let client: Client | null = null;
|
||||
let databases: Databases | null = null;
|
||||
let storage: Storage | null = null;
|
||||
|
||||
function ensureClient() {
|
||||
if (!endpoint || !projectId || !apiKey) return null;
|
||||
@@ -25,6 +38,7 @@ function ensureClient() {
|
||||
.setProject(projectId)
|
||||
.setKey(apiKey);
|
||||
databases = new Databases(client);
|
||||
storage = new Storage(client);
|
||||
return client;
|
||||
}
|
||||
|
||||
@@ -32,6 +46,10 @@ export function getDatabases(): Databases | null {
|
||||
return ensureClient() ? (databases as Databases) : null;
|
||||
}
|
||||
|
||||
export function getStorage(): Storage | null {
|
||||
return ensureClient() ? (storage as Storage) : null;
|
||||
}
|
||||
|
||||
export function isAppwriteConfigured(): boolean {
|
||||
return Boolean(
|
||||
endpoint &&
|
||||
@@ -61,3 +79,20 @@ export function isGuildCacheConfigured(): boolean {
|
||||
APPWRITE_COLLECTION_GUILD_CACHE_ID
|
||||
);
|
||||
}
|
||||
|
||||
export function isAppwriteStorageConfigured(): boolean {
|
||||
return Boolean(endpoint && projectId && apiKey && APPWRITE_BUCKET_IMAGES_ID);
|
||||
}
|
||||
|
||||
export function isGameRealtimeConfigured(): boolean {
|
||||
// minimal check for quests/progress and scheduled attacks mirrors
|
||||
return Boolean(
|
||||
endpoint &&
|
||||
projectId &&
|
||||
apiKey &&
|
||||
APPWRITE_DATABASE_ID &&
|
||||
(APPWRITE_COLLECTION_QUESTS_ID ||
|
||||
APPWRITE_COLLECTION_QUEST_PROGRESS_ID ||
|
||||
APPWRITE_COLLECTION_SCHEDULED_ATTACKS_ID)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
export type DisplayBlock =
|
||||
| { kind: 'text'; content: string }
|
||||
| { kind: 'divider'; divider?: boolean; spacing?: number };
|
||||
| { kind: "text"; content: string }
|
||||
| { kind: "divider"; divider?: boolean; spacing?: number }
|
||||
| { kind: "image"; url: string };
|
||||
|
||||
export const textBlock = (content: string): DisplayBlock => ({ kind: 'text', content });
|
||||
export const textBlock = (content: string): DisplayBlock => ({
|
||||
kind: "text",
|
||||
content,
|
||||
});
|
||||
|
||||
export const dividerBlock = (options: { divider?: boolean; spacing?: number } = {}): DisplayBlock => ({
|
||||
kind: 'divider',
|
||||
export const dividerBlock = (
|
||||
options: { divider?: boolean; spacing?: number } = {}
|
||||
): DisplayBlock => ({
|
||||
kind: "divider",
|
||||
divider: options.divider,
|
||||
spacing: options.spacing,
|
||||
});
|
||||
@@ -15,10 +21,15 @@ export function buildDisplay(accentColor: number, blocks: DisplayBlock[]) {
|
||||
type: 17 as const,
|
||||
accent_color: accentColor,
|
||||
components: blocks.map((block) => {
|
||||
if (block.kind === 'text') {
|
||||
if (block.kind === "text") {
|
||||
return { type: 10 as const, content: block.content };
|
||||
}
|
||||
|
||||
if (block.kind === "image") {
|
||||
// This component type will be translated by the renderer to an embed image
|
||||
return { type: 12 as const, url: block.url } as any;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 14 as const,
|
||||
divider: block.divider ?? true,
|
||||
|
||||
Reference in New Issue
Block a user