Initial commit
This commit is contained in:
commit
2f5e10140c
133 changed files with 10429 additions and 0 deletions
164
packages/shared/src/data.ts
Normal file
164
packages/shared/src/data.ts
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
import { z } from "zod";
|
||||
|
||||
import { legalDocsSchema } from "./features/legal/schema";
|
||||
import { community, conversation } from "./features/conversation/schema";
|
||||
|
||||
const fileFromMessage = z.object({
|
||||
name: z.string(),
|
||||
id: z.uuidv4(),
|
||||
type: z.enum(["image", "image_top_right", "file"]),
|
||||
});
|
||||
|
||||
const message = z.object({
|
||||
height: z.number(),
|
||||
not_encrypted: z.boolean().optional(),
|
||||
sent_by_self: z.boolean(),
|
||||
timestamp: z.number(),
|
||||
content: z.base64(),
|
||||
files: z.array(fileFromMessage).optional(),
|
||||
tint: z.string().length(7).startsWith("#").optional(),
|
||||
avatar: z.boolean().optional(),
|
||||
display: z.boolean().optional(),
|
||||
});
|
||||
|
||||
// Socket
|
||||
export const socket = {
|
||||
identification: {
|
||||
request: z.object({
|
||||
user_id: z.number(),
|
||||
}),
|
||||
response: z.object({
|
||||
challenge: z.string(),
|
||||
public_key: z.base64(),
|
||||
}),
|
||||
},
|
||||
get_user_data: {
|
||||
request: z.object({
|
||||
user_id: z.number(),
|
||||
}),
|
||||
response: z.object({
|
||||
about: z.string().max(255).optional(),
|
||||
avatar: z.string().optional(),
|
||||
display: z.string().max(15),
|
||||
iota_id: z.number(),
|
||||
omikron_connections: z.array(z.number()),
|
||||
omikron_id: z.number().optional(),
|
||||
online_status: z.enum([
|
||||
"user_offline",
|
||||
"user_online",
|
||||
"user_dnd",
|
||||
"user_idle",
|
||||
"user_wc",
|
||||
"user_borked",
|
||||
"iota_offline",
|
||||
"iota_online",
|
||||
"iota_borked",
|
||||
]),
|
||||
public_key: z.base64(),
|
||||
status: z.string().max(15).optional(),
|
||||
sub_end: z.number(),
|
||||
sub_level: z.number(),
|
||||
user_id: z.number(),
|
||||
username: z.string().max(15),
|
||||
}),
|
||||
},
|
||||
challenge_response: {
|
||||
request: z.object({
|
||||
challenge: z.base64(),
|
||||
}),
|
||||
response: z.object({}),
|
||||
},
|
||||
ping: {
|
||||
request: z.object({
|
||||
last_ping: z.number(),
|
||||
}),
|
||||
response: z.object({
|
||||
ping_iota: z.number(),
|
||||
}),
|
||||
},
|
||||
get_chats: {
|
||||
request: z.object({}),
|
||||
response: z.object({
|
||||
user_ids: z.array(conversation),
|
||||
}),
|
||||
},
|
||||
get_communities: {
|
||||
request: z.object({}),
|
||||
response: z.object({
|
||||
communities: z.array(community),
|
||||
}),
|
||||
},
|
||||
live_message: {
|
||||
request: z.object({}),
|
||||
response: z.object({
|
||||
sender_id: z.number(),
|
||||
send_time: z.number(),
|
||||
message,
|
||||
}),
|
||||
},
|
||||
messages_get: {
|
||||
request: z.object({
|
||||
user_id: z.number(),
|
||||
amount: z.number(),
|
||||
offset: z.number(),
|
||||
}),
|
||||
response: z.object({
|
||||
messages: z.array(message),
|
||||
}),
|
||||
},
|
||||
message_send: {
|
||||
request: z.object({
|
||||
height: z.number(),
|
||||
content: z.base64(),
|
||||
receiver_id: z.number(),
|
||||
send_time: z.number(),
|
||||
files: z.array(fileFromMessage).optional(),
|
||||
}),
|
||||
response: z.object({}),
|
||||
},
|
||||
} satisfies Record<string, { request: z.ZodType; response: z.ZodType }>;
|
||||
|
||||
export type Socket = typeof socket;
|
||||
|
||||
// Storage
|
||||
export interface Storage {
|
||||
user_id: number;
|
||||
private_key: string;
|
||||
ppandtos_done: boolean;
|
||||
accepted_terms_of_service: boolean;
|
||||
accepted_privacy_policy: boolean;
|
||||
analytics_crash_reports: boolean;
|
||||
analytics_usage_data: boolean;
|
||||
analytics_done: boolean;
|
||||
legal_docs: z.infer<typeof legalDocsSchema>;
|
||||
chat_invert_enter_behaviour: boolean;
|
||||
}
|
||||
|
||||
export const storageDefaults: Storage = {
|
||||
user_id: 0,
|
||||
private_key: "",
|
||||
ppandtos_done: false,
|
||||
accepted_terms_of_service: false,
|
||||
accepted_privacy_policy: false,
|
||||
analytics_crash_reports: true,
|
||||
analytics_usage_data: true,
|
||||
analytics_done: false,
|
||||
legal_docs: {
|
||||
eula: {
|
||||
version: "0.0",
|
||||
hash: "000000000000",
|
||||
unix: 0,
|
||||
},
|
||||
tos: {
|
||||
version: "0.0",
|
||||
hash: "000000000000",
|
||||
unix: 0,
|
||||
},
|
||||
pp: {
|
||||
version: "0.0",
|
||||
hash: "000000000000",
|
||||
unix: 0,
|
||||
},
|
||||
},
|
||||
chat_invert_enter_behaviour: false,
|
||||
};
|
||||
16
packages/shared/src/features/conversation/schema.ts
Normal file
16
packages/shared/src/features/conversation/schema.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export const conversation = z.object({
|
||||
user_id: z.number(),
|
||||
calls: z.array(z.uuidv4()).optional(),
|
||||
last_message_at: z.number(),
|
||||
});
|
||||
|
||||
export const community = z.object({
|
||||
community_address: z.string(),
|
||||
community_title: z.string(),
|
||||
position: z.string(),
|
||||
});
|
||||
|
||||
export type Conversation = z.infer<typeof conversation>;
|
||||
export type Community = z.infer<typeof community>;
|
||||
13
packages/shared/src/features/legal/schema.ts
Normal file
13
packages/shared/src/features/legal/schema.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { z } from "zod";
|
||||
|
||||
const legalDocSchema = z.object({
|
||||
version: z.string().regex(/^\d+\.\d+$/),
|
||||
hash: z.string().regex(/^[a-f0-9]{12}$/),
|
||||
unix: z.number().int().positive(),
|
||||
});
|
||||
|
||||
export const legalDocsSchema = z.object({
|
||||
eula: legalDocSchema,
|
||||
tos: legalDocSchema,
|
||||
pp: legalDocSchema,
|
||||
});
|
||||
52
packages/shared/src/log.tsx
Normal file
52
packages/shared/src/log.tsx
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { toast as sonnerToast } from "solid-sonner";
|
||||
import { Ban, Check, Info, TriangleAlert } from "lucide-solid";
|
||||
|
||||
export function log(
|
||||
logLevel: number,
|
||||
logger: string,
|
||||
color: "red" | "green" | "yellow" | "purple" | "blue",
|
||||
...args: unknown[]
|
||||
) {
|
||||
const currentLogLevel = Number(localStorage.getItem("log_level") || 0);
|
||||
|
||||
if (logLevel > currentLogLevel) return;
|
||||
|
||||
const colorCodes: Record<typeof color, string> = {
|
||||
red: "\x1b[31m",
|
||||
green: "\x1b[32m",
|
||||
yellow: "\x1b[33m",
|
||||
purple: "\x1b[35m",
|
||||
blue: "\x1b[34m",
|
||||
};
|
||||
const resetCode = "\x1b[0m";
|
||||
console.log(`${colorCodes[color]}[${logger}]${resetCode}`, ...args);
|
||||
}
|
||||
|
||||
const size = 20;
|
||||
export function toast(
|
||||
type: "error" | "info" | "warn" | "success",
|
||||
message: string,
|
||||
) {
|
||||
switch (type) {
|
||||
case "error":
|
||||
sonnerToast(message, {
|
||||
icon: <Ban size={size} />,
|
||||
});
|
||||
break;
|
||||
case "info":
|
||||
sonnerToast(message, {
|
||||
icon: <Info size={size} />,
|
||||
});
|
||||
break;
|
||||
case "warn":
|
||||
sonnerToast(message, {
|
||||
icon: <TriangleAlert size={size} />,
|
||||
});
|
||||
break;
|
||||
case "success":
|
||||
sonnerToast(message, {
|
||||
icon: <Check size={size} />,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue