@@ -23,12 +23,17 @@ import { User } from "./User";
2323import {
2424 FrecencyUserSettings ,
2525 PreloadedUserSettings ,
26+ PreloadedUserSettings_AppearanceSettings , PreloadedUserSettings_CustomStatus ,
2627 PreloadedUserSettings_LaunchPadMode ,
28+ PreloadedUserSettings_PrivacySettings , PreloadedUserSettings_StatusSettings ,
2729 PreloadedUserSettings_SwipeRightToLeftMode ,
30+ PreloadedUserSettings_TextAndImagesSettings ,
2831 PreloadedUserSettings_Theme ,
2932 PreloadedUserSettings_TimestampHourCycle ,
3033 PreloadedUserSettings_UIDensity ,
34+ PreloadedUserSettings_VoiceAndVideoSettings ,
3135} from "discord-protos" ;
36+ import { BoolValue , UInt32Value } from "discord-protos/dist/discord_protos/google/protobuf/wrappers" ;
3237
3338@Entity ( {
3439 name : "user_settings_protos" ,
@@ -55,50 +60,13 @@ export class UserSettingsProtos extends BaseClassWithoutId {
5560 // @Column ({nullable: true, type: "simple-json"})
5661 // testSettings: {};
5762
58- bigintReplacer ( _key : string , value : any ) : any {
59- if ( typeof value === "bigint" ) {
60- return ( value as bigint ) . toString ( ) ;
61- } else if ( value instanceof Uint8Array ) {
62- return {
63- __type : "Uint8Array" ,
64- data : Array . from ( value as Uint8Array )
65- . map ( ( b ) => b . toString ( 16 ) . padStart ( 2 , "0" ) )
66- . join ( "" ) ,
67- } ;
68- } else {
69- return value ;
70- }
71- }
72-
73- bigintReviver ( _key : string , value : any ) : any {
74- if ( typeof value === "string" && / ^ \d + n $ / . test ( value ) ) {
75- return BigInt ( ( value as string ) . slice ( 0 , - 1 ) ) ;
76- } else if (
77- typeof value === "object" &&
78- value !== null &&
79- "__type" in value
80- ) {
81- if ( value . __type === "Uint8Array" && "data" in value ) {
82- return new Uint8Array (
83- value . data
84- . match ( / .{ 1 , 2 } / g) !
85- . map ( ( byte : string ) => parseInt ( byte , 16 ) ) ,
86- ) ;
87- }
88- }
89- return value ;
90- }
91-
9263 get userSettings ( ) : PreloadedUserSettings | undefined {
9364 if ( ! this . _userSettings ) return undefined ;
94- return PreloadedUserSettings . fromJson (
95- JSON . parse ( this . _userSettings , this . bigintReviver ) ,
96- ) ;
65+ return PreloadedUserSettings . fromJsonString ( this . _userSettings ) ;
9766 }
9867
9968 set userSettings ( value : PreloadedUserSettings | undefined ) {
10069 if ( value ) {
101- // this._userSettings = JSON.stringify(value, this.bigintReplacer);
10270 this . _userSettings = PreloadedUserSettings . toJsonString ( value ) ;
10371 } else {
10472 this . _userSettings = undefined ;
@@ -107,35 +75,32 @@ export class UserSettingsProtos extends BaseClassWithoutId {
10775
10876 get frecencySettings ( ) : FrecencyUserSettings | undefined {
10977 if ( ! this . _frecencySettings ) return undefined ;
110- return FrecencyUserSettings . fromJson (
111- JSON . parse ( this . _frecencySettings , this . bigintReviver ) ,
112- ) ;
78+ return FrecencyUserSettings . fromJsonString ( this . _frecencySettings ) ;
11379 }
11480
11581 set frecencySettings ( value : FrecencyUserSettings | undefined ) {
11682 if ( value ) {
117- this . _frecencySettings = JSON . stringify ( value , this . bigintReplacer ) ;
83+ this . _frecencySettings = FrecencyUserSettings . toJsonString ( value ) ;
11884 } else {
11985 this . _frecencySettings = undefined ;
12086 }
12187 }
12288
12389 static async getOrCreate ( user_id : string ) : Promise < UserSettingsProtos > {
124- const user = await User . findOneOrFail ( {
125- where : { id : user_id } ,
126- select : { settings : true } ,
127- } ) ;
90+ if ( ! ( await User . existsBy ( { id : user_id } ) ) ) throw new Error ( `User with ID ${ user_id } does not exist.` ) ;
12891
12992 let userSettings = await UserSettingsProtos . findOne ( {
13093 where : { user_id } ,
13194 } ) ;
13295
13396 let modified = false ;
97+ let isNewSettings = false ;
13498 if ( ! userSettings ) {
13599 userSettings = UserSettingsProtos . create ( {
136100 user_id,
137101 } ) ;
138102 modified = true ;
103+ isNewSettings = true ;
139104 }
140105
141106 if ( ! userSettings . userSettings ) {
@@ -176,8 +141,74 @@ export class UserSettingsProtos extends BaseClassWithoutId {
176141 modified = true ;
177142 }
178143
144+ if ( isNewSettings ) userSettings = await this . importLegacySettings ( user_id , userSettings ) ;
145+
179146 if ( modified ) userSettings = await userSettings . save ( ) ;
180147
181148 return userSettings ;
182149 }
183- }
150+
151+ static async importLegacySettings ( user_id : string , settings : UserSettingsProtos ) : Promise < UserSettingsProtos > {
152+ const user = await User . findOneOrFail ( {
153+ where : { id : user_id } ,
154+ select : { settings : true } ,
155+ } ) ;
156+ if ( ! user ) throw new Error ( `User with ID ${ user_id } does not exist.` ) ;
157+
158+ const legacySettings = user . settings ;
159+ const { frecencySettings, userSettings } = settings ;
160+
161+ if ( userSettings === undefined ) {
162+ throw new Error ( "UserSettingsProtos.userSettings is undefined, this should not happen." ) ;
163+ }
164+ if ( frecencySettings === undefined ) {
165+ throw new Error ( "UserSettingsProtos.frecencySettings is undefined, this should not happen." ) ;
166+ }
167+
168+ if ( legacySettings ) {
169+ if ( legacySettings . afk_timeout !== null && legacySettings . afk_timeout !== undefined ) {
170+ userSettings . voiceAndVideo ??= PreloadedUserSettings_VoiceAndVideoSettings . create ( ) ;
171+ userSettings . voiceAndVideo . afkTimeout = UInt32Value . fromJson ( legacySettings . afk_timeout ) ;
172+ }
173+
174+ if ( legacySettings . allow_accessibility_detection !== null && legacySettings . allow_accessibility_detection !== undefined ) {
175+ userSettings . privacy ??= PreloadedUserSettings_PrivacySettings . create ( ) ;
176+ userSettings . privacy . allowAccessibilityDetection = legacySettings . allow_accessibility_detection ;
177+ }
178+
179+ if ( legacySettings . animate_emoji !== null && legacySettings . animate_emoji !== undefined ) {
180+ userSettings . textAndImages ??= PreloadedUserSettings_TextAndImagesSettings . create ( ) ;
181+ userSettings . textAndImages . animateEmoji = BoolValue . fromJson ( legacySettings . animate_emoji ) ;
182+ }
183+
184+ if ( legacySettings . animate_stickers !== null && legacySettings . animate_stickers !== undefined ) {
185+ userSettings . textAndImages ??= PreloadedUserSettings_TextAndImagesSettings . create ( ) ;
186+ userSettings . textAndImages . animateStickers = UInt32Value . fromJson ( legacySettings . animate_stickers ) ;
187+ }
188+
189+ if ( legacySettings . contact_sync_enabled !== null && legacySettings . contact_sync_enabled !== undefined ) {
190+ userSettings . privacy ??= PreloadedUserSettings_PrivacySettings . create ( ) ;
191+ userSettings . privacy . contactSyncEnabled = BoolValue . fromJson ( legacySettings . contact_sync_enabled ) ;
192+ }
193+
194+ if ( legacySettings . convert_emoticons !== null && legacySettings . convert_emoticons !== undefined ) {
195+ userSettings . textAndImages ??= PreloadedUserSettings_TextAndImagesSettings . create ( ) ;
196+ userSettings . textAndImages . convertEmoticons = BoolValue . fromJson ( legacySettings . convert_emoticons ) ;
197+ }
198+
199+ if ( legacySettings . custom_status !== null && legacySettings . custom_status !== undefined ) {
200+ userSettings . status ??= PreloadedUserSettings_StatusSettings . create ( ) ;
201+ userSettings . status . customStatus = PreloadedUserSettings_CustomStatus . create ( {
202+ emojiId : legacySettings . custom_status . emoji_id === undefined ? undefined : BigInt ( legacySettings . custom_status . emoji_id ) as bigint ,
203+ emojiName : legacySettings . custom_status . emoji_name ,
204+ expiresAtMs : legacySettings . custom_status . expires_at === undefined ? undefined : BigInt ( legacySettings . custom_status . expires_at ) as bigint ,
205+ text : legacySettings . custom_status . text ,
206+ createdAtMs : BigInt ( Date . now ( ) ) as bigint ,
207+ } ) ;
208+ }
209+
210+ }
211+
212+ return settings ;
213+ }
214+ }
0 commit comments