mirror of
https://github.com/YuzuZensai/VRC-Circle.git
synced 2026-09-13 19:08:52 +00:00
✨ feat: Initial commit
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
export interface AppConfig {
|
||||
version: string;
|
||||
gamePath: string | null;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
export type TwoFactorMethod = "totp" | "emailOtp";
|
||||
|
||||
export type AuthStatus =
|
||||
| { state: "unauthenticated" }
|
||||
| { state: "awaiting2fa"; methods: TwoFactorMethod[] }
|
||||
| { state: "authenticated"; user: CurrentUserSummary };
|
||||
|
||||
export interface CurrentUserSummary {
|
||||
id: string;
|
||||
displayName: string;
|
||||
userIcon: string;
|
||||
currentAvatarThumbnailImageUrl: string;
|
||||
}
|
||||
|
||||
export interface Account {
|
||||
id: string;
|
||||
displayName: string;
|
||||
userIcon: string;
|
||||
}
|
||||
|
||||
export interface AccountsState {
|
||||
accounts: Account[];
|
||||
activeId: string | null;
|
||||
}
|
||||
|
||||
export interface LoginCredentials {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface TwoFactorPayload {
|
||||
method: TwoFactorMethod;
|
||||
code: string;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export interface Avatar {
|
||||
id: string;
|
||||
name: string;
|
||||
authorId: string;
|
||||
authorName: string;
|
||||
description: string;
|
||||
imageUrl: string;
|
||||
thumbnailImageUrl: string;
|
||||
releaseStatus: string;
|
||||
tags: string[];
|
||||
favorites: number;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import type { RepoStats } from "./repository";
|
||||
|
||||
export type LogLevel = "debug" | "info" | "warn" | "error";
|
||||
|
||||
export interface LogEntry {
|
||||
id: number;
|
||||
ts: number;
|
||||
level: LogLevel;
|
||||
scope: string;
|
||||
message: string;
|
||||
data?: unknown;
|
||||
}
|
||||
|
||||
export type CacheStatus = "fresh" | "stale" | "expired";
|
||||
|
||||
export interface CacheEntryInfo {
|
||||
key: string;
|
||||
createdAt: number;
|
||||
expiresAt: number;
|
||||
hardExpiresAt: number;
|
||||
hits: number;
|
||||
lastAccess: number;
|
||||
size: number;
|
||||
value: unknown;
|
||||
}
|
||||
|
||||
export interface CacheStats {
|
||||
entries: number;
|
||||
inflight: number;
|
||||
totalSize: number;
|
||||
fresh: number;
|
||||
stale: number;
|
||||
expired: number;
|
||||
hits: number;
|
||||
misses: number;
|
||||
sets: number;
|
||||
patches: number;
|
||||
revalidations: number;
|
||||
invalidations: number;
|
||||
clears: number;
|
||||
persisted: boolean;
|
||||
persistFile: string | null;
|
||||
}
|
||||
|
||||
export interface WsEvent {
|
||||
id: number;
|
||||
ts: number;
|
||||
type: string;
|
||||
handled: boolean;
|
||||
content: unknown;
|
||||
}
|
||||
|
||||
export interface DebugSnapshot {
|
||||
cache: CacheEntryInfo[];
|
||||
stats: CacheStats;
|
||||
logs: LogEntry[];
|
||||
ws: WsEvent[];
|
||||
repos: RepoStats[];
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
export type EnhancementId = "linux-screenshot-symlink";
|
||||
|
||||
export type OsPlatform = "linux" | "win32" | "darwin";
|
||||
|
||||
export interface EnhancementDetail {
|
||||
key: string;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
export interface EnhancementState {
|
||||
id: EnhancementId;
|
||||
enabled: boolean;
|
||||
detail?: EnhancementDetail;
|
||||
resolvedPath?: string;
|
||||
}
|
||||
|
||||
export interface EnhancementsSnapshot {
|
||||
platform: OsPlatform;
|
||||
states: EnhancementState[];
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
export interface PhotoMetadata {
|
||||
author?: string;
|
||||
authorId?: string;
|
||||
worldId?: string;
|
||||
worldName?: string;
|
||||
takenAt?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
}
|
||||
|
||||
export interface Photo {
|
||||
id: string;
|
||||
fileName: string;
|
||||
bucket: string;
|
||||
src: string;
|
||||
thumb: string;
|
||||
sizeBytes: number;
|
||||
modifiedAt: string;
|
||||
metadata: PhotoMetadata;
|
||||
}
|
||||
|
||||
export interface ThumbCacheStats {
|
||||
count: number;
|
||||
totalBytes: number;
|
||||
dir: string;
|
||||
}
|
||||
|
||||
export interface GallerySnapshot {
|
||||
roots: string[];
|
||||
empty: boolean;
|
||||
photos: Photo[];
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface GameStatus {
|
||||
running: boolean;
|
||||
supported: boolean;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
export interface Group {
|
||||
id: string;
|
||||
name: string;
|
||||
shortCode?: string;
|
||||
description?: string;
|
||||
iconUrl?: string;
|
||||
bannerUrl?: string;
|
||||
ownerId?: string;
|
||||
memberCount?: number;
|
||||
privacy?: string;
|
||||
isRepresenting?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
export type FieldSource = "ws" | "rest:detail" | "rest:list" | "rest:search" | "seed";
|
||||
|
||||
export interface FieldMeta {
|
||||
at: number;
|
||||
src: FieldSource;
|
||||
}
|
||||
|
||||
export interface EntityMeta {
|
||||
fields: Record<string, FieldMeta>;
|
||||
firstSeen: number;
|
||||
lastRead: number;
|
||||
lastFetch: number;
|
||||
}
|
||||
|
||||
export interface StoredEntity<T> {
|
||||
data: T;
|
||||
meta: EntityMeta;
|
||||
}
|
||||
|
||||
export interface RepoStats {
|
||||
name: string;
|
||||
count: number;
|
||||
totalSize: number;
|
||||
oldestRead: number | null;
|
||||
newestFetch: number | null;
|
||||
pendingWrites: number;
|
||||
backendFile: string | null;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
export type ApiErrorCode =
|
||||
| "unauthorized"
|
||||
| "requires_2fa"
|
||||
| "invalid_2fa"
|
||||
| "rate_limited"
|
||||
| "not_found"
|
||||
| "network"
|
||||
| "unknown";
|
||||
|
||||
export interface ApiError {
|
||||
code: ApiErrorCode;
|
||||
message: string;
|
||||
retryAfter?: number;
|
||||
methods?: ("totp" | "emailOtp")[];
|
||||
}
|
||||
|
||||
export type IpcResult<T> = { ok: true; data: T } | { ok: false; error: ApiError };
|
||||
@@ -0,0 +1,46 @@
|
||||
export type ContentFilterKey =
|
||||
| "content_sex"
|
||||
| "content_adult"
|
||||
| "content_violence"
|
||||
| "content_gore"
|
||||
| "content_horror";
|
||||
|
||||
export interface AccountLink {
|
||||
linked: boolean;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export interface AccountSettings {
|
||||
id: string;
|
||||
displayName: string;
|
||||
displayNameChangedAt?: string;
|
||||
previousDisplayName?: string;
|
||||
supporter: boolean;
|
||||
pronouns: string;
|
||||
email: string;
|
||||
emailVerified: boolean;
|
||||
pendingEmail?: string;
|
||||
twoFactorEnabled: boolean;
|
||||
twoFactorEnabledDate?: string;
|
||||
usesGeneratedPassword: boolean;
|
||||
ageVerificationStatus: "18+" | "hidden" | "verified";
|
||||
ageVerified: boolean;
|
||||
isAdult: boolean;
|
||||
contentFilters: ContentFilterKey[];
|
||||
contentFiltersLocked: boolean;
|
||||
sharedConnectionsHidden: boolean;
|
||||
discordFriendsHidden: boolean;
|
||||
discord: AccountLink;
|
||||
google: AccountLink;
|
||||
accountDeletionDate?: string | null;
|
||||
}
|
||||
|
||||
export interface Pending2Fa {
|
||||
secret: string;
|
||||
qrCodeDataUrl: string;
|
||||
}
|
||||
|
||||
export interface RecoveryCode {
|
||||
code: string;
|
||||
used: boolean;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
export type TrustRank =
|
||||
| "visitor"
|
||||
| "new"
|
||||
| "user"
|
||||
| "known"
|
||||
| "trusted"
|
||||
| "veteran"
|
||||
| "nuisance"
|
||||
| "troll";
|
||||
|
||||
export type UserStatus = "active" | "join me" | "ask me" | "busy" | "offline";
|
||||
|
||||
export type Platform = "standalonewindows" | "android" | "web" | "offline" | string;
|
||||
|
||||
export type Location = "offline" | "private" | "traveling" | "" | string;
|
||||
|
||||
export interface ParsedLocation {
|
||||
worldId: string;
|
||||
instanceId: string;
|
||||
region?: string;
|
||||
}
|
||||
|
||||
export function parseLocation(loc?: string): ParsedLocation | null {
|
||||
if (!loc || loc === "offline" || loc === "private" || loc === "traveling") return null;
|
||||
const [worldId, rest] = loc.split(":");
|
||||
if (!worldId?.startsWith("wrld_") || !rest) return null;
|
||||
const instanceId = rest.split("~")[0];
|
||||
const region = /~region\(([^)]+)\)/.exec(rest)?.[1];
|
||||
return { worldId, instanceId, region };
|
||||
}
|
||||
|
||||
export interface Badge {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
imageUrl: string;
|
||||
showcased: boolean;
|
||||
}
|
||||
|
||||
export interface UserProfile {
|
||||
id: string;
|
||||
displayName: string;
|
||||
bio: string;
|
||||
bioLinks: string[];
|
||||
statusDescription: string;
|
||||
status: UserStatus;
|
||||
trustRank: TrustRank;
|
||||
tags: string[];
|
||||
|
||||
userIcon: string;
|
||||
profilePicOverride: string;
|
||||
profilePicOverrideThumbnail: string;
|
||||
currentAvatarImageUrl: string;
|
||||
currentAvatarThumbnailImageUrl: string;
|
||||
currentAvatarTags: string[];
|
||||
|
||||
location?: Location;
|
||||
lastPlatform?: Platform;
|
||||
lastLogin?: string;
|
||||
lastActivity?: string;
|
||||
state?: "online" | "active" | "offline";
|
||||
platform?: Platform;
|
||||
|
||||
isFriend: boolean;
|
||||
friendKey?: string;
|
||||
|
||||
developerType?: "none" | "trusted" | "internal" | "moderator" | string;
|
||||
ageVerificationStatus?: string;
|
||||
ageVerified?: boolean;
|
||||
pronouns?: string;
|
||||
languages?: string[];
|
||||
dateJoined?: string;
|
||||
pastDisplayNames?: { displayName: string; updatedAt?: string }[];
|
||||
note?: string;
|
||||
badges: Badge[];
|
||||
|
||||
isSelf: boolean;
|
||||
}
|
||||
|
||||
export interface SocialSnapshot {
|
||||
selfId: string | null;
|
||||
users: UserProfile[];
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
export type ReleaseStatus = "public" | "private" | "hidden" | "all";
|
||||
|
||||
export interface WorldPlatforms {
|
||||
pc: boolean;
|
||||
android: boolean;
|
||||
}
|
||||
|
||||
export interface World {
|
||||
id: string;
|
||||
detailed: boolean;
|
||||
name: string;
|
||||
authorId: string;
|
||||
authorName: string;
|
||||
description: string;
|
||||
imageUrl: string;
|
||||
thumbnailImageUrl: string;
|
||||
releaseStatus: ReleaseStatus;
|
||||
capacity: number;
|
||||
favorites: number;
|
||||
visits: number;
|
||||
occupants: number;
|
||||
heat: number;
|
||||
tags: string[];
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
|
||||
recommendedCapacity?: number;
|
||||
popularity?: number;
|
||||
version?: number;
|
||||
publishedAt?: string;
|
||||
labsPublishedAt?: string;
|
||||
previewYoutubeId?: string;
|
||||
platforms?: WorldPlatforms;
|
||||
publicOccupants?: number;
|
||||
privateOccupants?: number;
|
||||
}
|
||||
|
||||
export interface WorldSnapshot {
|
||||
worlds: World[];
|
||||
byAuthor: Record<string, string[]>;
|
||||
}
|
||||
|
||||
export interface FavoriteWorldFolder {
|
||||
name: string;
|
||||
displayName: string;
|
||||
worldIds: string[];
|
||||
}
|
||||
Reference in New Issue
Block a user