summary refs log tree commit diff
path: root/src/database/entities/UserSettingsProtos.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/database/entities/UserSettingsProtos.ts')
-rw-r--r--src/database/entities/UserSettingsProtos.ts145
1 files changed, 145 insertions, 0 deletions
diff --git a/src/database/entities/UserSettingsProtos.ts b/src/database/entities/UserSettingsProtos.ts
new file mode 100644

index 00000000..c8ee9d12 --- /dev/null +++ b/src/database/entities/UserSettingsProtos.ts
@@ -0,0 +1,145 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2025 Spacebar and Spacebar Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +import { Column, Entity, JoinColumn, OneToOne, PrimaryColumn } from "typeorm"; +import { BaseClassWithoutId } from "./BaseClass"; +import { User } from "./User"; +import { FrecencyUserSettings, PreloadedUserSettings } from "discord-protos"; + +@Entity({ + name: "user_settings_protos", +}) +export class UserSettingsProtos extends BaseClassWithoutId { + @OneToOne(() => User, { + cascade: true, + orphanedRowAction: "delete", + eager: false, + }) + @JoinColumn({ name: "user_id" }) + user: User; + + @PrimaryColumn({ type: "text" }) + user_id: string; + + @Column({ nullable: true, type: String, name: "userSettings" }) + _userSettings: string | undefined; + + @Column({ nullable: true, type: String, name: "frecencySettings" }) + _frecencySettings: string | undefined; + + // @Column({nullable: true, type: "simple-json"}) + // testSettings: {}; + + bigintReplacer(_key: string, value: unknown): unknown { + if (typeof value === "bigint") { + return (value as bigint).toString(); + } else if (value instanceof Uint8Array) { + return { + __type: "Uint8Array", + data: Array.from(value as Uint8Array) + .map((b) => b.toString(16).padStart(2, "0")) + .join(""), + }; + } else { + return value; + } + } + + bigintReviver(_key: string, value: unknown): unknown { + if (typeof value === "string" && /^\d+n$/.test(value)) { + return BigInt((value as string).slice(0, -1)); + } else if (typeof value === "object" && value !== null && "__type" in value) { + if (value.__type === "Uint8Array" && "data" in value) { + return new Uint8Array((value.data as string).match(/.{1,2}/g)!.map((byte: string) => parseInt(byte, 16))); + } + } + return value; + } + + get userSettings(): PreloadedUserSettings | undefined { + if (!this._userSettings) return undefined; + return PreloadedUserSettings.fromJson(JSON.parse(this._userSettings, this.bigintReviver)); + } + + set userSettings(value: PreloadedUserSettings | undefined) { + if (value) { + // this._userSettings = JSON.stringify(value, this.bigintReplacer); + this._userSettings = PreloadedUserSettings.toJsonString(value); + } else { + this._userSettings = undefined; + } + } + + get frecencySettings(): FrecencyUserSettings | undefined { + if (!this._frecencySettings) return undefined; + return FrecencyUserSettings.fromJson(JSON.parse(this._frecencySettings, this.bigintReviver)); + } + + set frecencySettings(value: FrecencyUserSettings | undefined) { + if (value) { + this._frecencySettings = JSON.stringify(value, this.bigintReplacer); + } else { + this._frecencySettings = undefined; + } + } + + static async getOrDefault(user_id: string, save: boolean = false): Promise<UserSettingsProtos> { + await User.findOneOrFail({ + where: { id: user_id }, + select: { settings: true }, + }); + + let userSettings = await UserSettingsProtos.findOne({ + where: { user_id }, + }); + + let modified = false; + if (!userSettings) { + userSettings = UserSettingsProtos.create({ + user_id, + }); + modified = true; + } + + if (!userSettings.userSettings) { + userSettings.userSettings = PreloadedUserSettings.create({ + versions: { + dataVersion: 0, + clientVersion: 0, + serverVersion: 0, + }, + }); + modified = true; + } + + if (!userSettings.frecencySettings) { + userSettings.frecencySettings = FrecencyUserSettings.create({ + versions: { + dataVersion: 0, + clientVersion: 0, + serverVersion: 0, + }, + }); + modified = true; + } + + if (modified && save) userSettings = await userSettings.save(); + + return userSettings; + } +}