1919import { Column , Entity , JoinColumn , OneToOne } from "typeorm" ;
2020import { BaseClassWithoutId , PrimaryIdColumn } from "./BaseClass" ;
2121import { User } from "./User" ;
22- import { FrecencyUserSettings , PreloadedUserSettings } from "discord-protos" ;
22+ import {
23+ FrecencyUserSettings ,
24+ PreloadedUserSettings ,
25+ PreloadedUserSettings_AppearanceSettings ,
26+ PreloadedUserSettings_CustomStatus ,
27+ PreloadedUserSettings_LaunchPadMode ,
28+ PreloadedUserSettings_PrivacySettings ,
29+ PreloadedUserSettings_StatusSettings ,
30+ PreloadedUserSettings_SwipeRightToLeftMode ,
31+ PreloadedUserSettings_TextAndImagesSettings ,
32+ PreloadedUserSettings_Theme ,
33+ PreloadedUserSettings_TimestampHourCycle ,
34+ PreloadedUserSettings_UIDensity ,
35+ PreloadedUserSettings_VoiceAndVideoSettings ,
36+ } from "discord-protos" ;
37+ import { BoolValue , UInt32Value } from "discord-protos/dist/discord_protos/google/protobuf/wrappers" ;
2338
2439@Entity ( {
2540 name : "user_settings_protos" ,
@@ -45,40 +60,13 @@ export class UserSettingsProtos extends BaseClassWithoutId {
4560 // @Column ({nullable: true, type: "simple-json"})
4661 // testSettings: {};
4762
48- bigintReplacer ( _key : string , value : unknown ) : unknown {
49- if ( typeof value === "bigint" ) {
50- return ( value as bigint ) . toString ( ) ;
51- } else if ( value instanceof Uint8Array ) {
52- return {
53- __type : "Uint8Array" ,
54- data : Array . from ( value as Uint8Array )
55- . map ( ( b ) => b . toString ( 16 ) . padStart ( 2 , "0" ) )
56- . join ( "" ) ,
57- } ;
58- } else {
59- return value ;
60- }
61- }
62-
63- bigintReviver ( _key : string , value : unknown ) : unknown {
64- if ( typeof value === "string" && / ^ \d + n $ / . test ( value ) ) {
65- return BigInt ( ( value as string ) . slice ( 0 , - 1 ) ) ;
66- } else if ( typeof value === "object" && value !== null && "__type" in value ) {
67- if ( value . __type === "Uint8Array" && "data" in value ) {
68- return new Uint8Array ( ( value . data as string ) . match ( / .{ 1 , 2 } / g) ! . map ( ( byte : string ) => parseInt ( byte , 16 ) ) ) ;
69- }
70- }
71- return value ;
72- }
73-
7463 get userSettings ( ) : PreloadedUserSettings | undefined {
7564 if ( ! this . _userSettings ) return undefined ;
76- return PreloadedUserSettings . fromJson ( JSON . parse ( this . _userSettings , this . bigintReviver ) ) ;
65+ return PreloadedUserSettings . fromJsonString ( this . _userSettings ) ;
7766 }
7867
7968 set userSettings ( value : PreloadedUserSettings | undefined ) {
8069 if ( value ) {
81- // this._userSettings = JSON.stringify(value, this.bigintReplacer);
8270 this . _userSettings = PreloadedUserSettings . toJsonString ( value ) ;
8371 } else {
8472 this . _userSettings = undefined ;
@@ -87,33 +75,32 @@ export class UserSettingsProtos extends BaseClassWithoutId {
8775
8876 get frecencySettings ( ) : FrecencyUserSettings | undefined {
8977 if ( ! this . _frecencySettings ) return undefined ;
90- return FrecencyUserSettings . fromJson ( JSON . parse ( this . _frecencySettings , this . bigintReviver ) ) ;
78+ return FrecencyUserSettings . fromJsonString ( this . _frecencySettings ) ;
9179 }
9280
9381 set frecencySettings ( value : FrecencyUserSettings | undefined ) {
9482 if ( value ) {
95- this . _frecencySettings = JSON . stringify ( value , this . bigintReplacer ) ;
83+ this . _frecencySettings = FrecencyUserSettings . toJsonString ( value ) ;
9684 } else {
9785 this . _frecencySettings = undefined ;
9886 }
9987 }
10088
101- static async getOrDefault ( user_id : string , save : boolean = false ) : Promise < UserSettingsProtos > {
102- const user = await User . findOneOrFail ( {
103- where : { id : user_id } ,
104- select : { settings : true } ,
105- } ) ;
89+ static async getOrCreate ( user_id : string , save : boolean = false ) : Promise < UserSettingsProtos > {
90+ if ( ! ( await User . existsBy ( { id : user_id } ) ) ) throw new Error ( `User with ID ${ user_id } does not exist.` ) ;
10691
10792 let userSettings = await UserSettingsProtos . findOne ( {
10893 where : { user_id } ,
10994 } ) ;
11095
11196 let modified = false ;
97+ let isNewSettings = false ;
11298 if ( ! userSettings ) {
11399 userSettings = UserSettingsProtos . create ( {
114100 user_id,
115101 } ) ;
116102 modified = true ;
103+ isNewSettings = true ;
117104 }
118105
119106 if ( ! userSettings . userSettings ) {
@@ -150,8 +137,73 @@ export class UserSettingsProtos extends BaseClassWithoutId {
150137 modified = true ;
151138 }
152139
140+ if ( isNewSettings ) userSettings = await this . importLegacySettings ( user_id , userSettings ) ;
141+
153142 if ( modified && save ) userSettings = await userSettings . save ( ) ;
154143
155144 return userSettings ;
156145 }
146+
147+ static async importLegacySettings ( user_id : string , settings : UserSettingsProtos ) : Promise < UserSettingsProtos > {
148+ const user = await User . findOneOrFail ( {
149+ where : { id : user_id } ,
150+ select : { settings : true } ,
151+ } ) ;
152+ if ( ! user ) throw new Error ( `User with ID ${ user_id } does not exist.` ) ;
153+
154+ const legacySettings = user . settings ;
155+ const { frecencySettings, userSettings } = settings ;
156+
157+ if ( userSettings === undefined ) {
158+ throw new Error ( "UserSettingsProtos.userSettings is undefined, this should not happen." ) ;
159+ }
160+ if ( frecencySettings === undefined ) {
161+ throw new Error ( "UserSettingsProtos.frecencySettings is undefined, this should not happen." ) ;
162+ }
163+
164+ if ( legacySettings ) {
165+ if ( legacySettings . afk_timeout !== null && legacySettings . afk_timeout !== undefined ) {
166+ userSettings . voiceAndVideo ??= PreloadedUserSettings_VoiceAndVideoSettings . create ( ) ;
167+ userSettings . voiceAndVideo . afkTimeout = UInt32Value . fromJson ( legacySettings . afk_timeout ) ;
168+ }
169+
170+ if ( legacySettings . allow_accessibility_detection !== null && legacySettings . allow_accessibility_detection !== undefined ) {
171+ userSettings . privacy ??= PreloadedUserSettings_PrivacySettings . create ( ) ;
172+ userSettings . privacy . allowAccessibilityDetection = legacySettings . allow_accessibility_detection ;
173+ }
174+
175+ if ( legacySettings . animate_emoji !== null && legacySettings . animate_emoji !== undefined ) {
176+ userSettings . textAndImages ??= PreloadedUserSettings_TextAndImagesSettings . create ( ) ;
177+ userSettings . textAndImages . animateEmoji = BoolValue . fromJson ( legacySettings . animate_emoji ) ;
178+ }
179+
180+ if ( legacySettings . animate_stickers !== null && legacySettings . animate_stickers !== undefined ) {
181+ userSettings . textAndImages ??= PreloadedUserSettings_TextAndImagesSettings . create ( ) ;
182+ userSettings . textAndImages . animateStickers = UInt32Value . fromJson ( legacySettings . animate_stickers ) ;
183+ }
184+
185+ if ( legacySettings . contact_sync_enabled !== null && legacySettings . contact_sync_enabled !== undefined ) {
186+ userSettings . privacy ??= PreloadedUserSettings_PrivacySettings . create ( ) ;
187+ userSettings . privacy . contactSyncEnabled = BoolValue . fromJson ( legacySettings . contact_sync_enabled ) ;
188+ }
189+
190+ if ( legacySettings . convert_emoticons !== null && legacySettings . convert_emoticons !== undefined ) {
191+ userSettings . textAndImages ??= PreloadedUserSettings_TextAndImagesSettings . create ( ) ;
192+ userSettings . textAndImages . convertEmoticons = BoolValue . fromJson ( legacySettings . convert_emoticons ) ;
193+ }
194+
195+ if ( legacySettings . custom_status !== null && legacySettings . custom_status !== undefined ) {
196+ userSettings . status ??= PreloadedUserSettings_StatusSettings . create ( ) ;
197+ userSettings . status . customStatus = PreloadedUserSettings_CustomStatus . create ( {
198+ emojiId : legacySettings . custom_status . emoji_id === undefined ? undefined : ( BigInt ( legacySettings . custom_status . emoji_id ) as bigint ) ,
199+ emojiName : legacySettings . custom_status . emoji_name ,
200+ expiresAtMs : legacySettings . custom_status . expires_at === undefined ? undefined : ( BigInt ( legacySettings . custom_status . expires_at ) as bigint ) ,
201+ text : legacySettings . custom_status . text ,
202+ createdAtMs : BigInt ( Date . now ( ) ) as bigint ,
203+ } ) ;
204+ }
205+ }
206+
207+ return settings ;
208+ }
157209}
0 commit comments