123
123
padding : 10px ;
124
124
}
125
125
126
+ button .for-icon {
127
+ padding : 10px ;
128
+ }
129
+
126
130
button > .icon {
127
131
margin-right : 5px ;
128
132
font-size : 1.4rem ;
487
491
max-height : 100px ;
488
492
font-family : Arial, sans-serif;
489
493
}
494
+
495
+ button .icon : last-child {
496
+ margin : 0 ;
497
+ }
490
498
</ style >
491
499
< style id ="dynamicStyles "> </ style >
492
500
< title > Limits Editor</ title >
495
503
< body >
496
504
< div class ="start-screen " id ="start-screen ">
497
505
< h1 > Telegram Limits Editor</ h1 >
506
+ < article >
507
+ < p >
508
+ Click the button below to suggest an edit to the @tginfo team.
509
+ </ p >
510
+ < p >
511
+ < b > Note</ b > : We do not accept translations through this form. Please go to < a
512
+ href ="https://crowdin.com/project/telegram-limits " target ="_blank "> Crowdin</ a > for translation.
513
+ </ p >
514
+ </ article >
515
+ < p >
516
+ < button onclick ="EditorUi.startSubmission() " id ="suggestButton "> Suggest an Edit</ button >
517
+ </ p >
498
518
< article >
499
519
< p > Edit limits in your cloned Telegram-Limits folder. When you click Save – files are updated right on your
500
520
disk. No downloads required.</ p >
@@ -509,7 +529,7 @@ <h1>Telegram Limits Editor</h1>
509
529
< p > < code > git clone git@github.com:tginfo/Telegram-Limits.git</ code > </ p >
510
530
</ article >
511
531
< p >
512
- < button onclick ="EditorUi.newSession() "> Pick < code > Telegram-Limits</ code > Folder</ button >
532
+ < button onclick ="EditorUi.newSession() " class =" secondary " > Pick < code > Telegram-Limits</ code > Folder</ button >
513
533
514
534
< button onclick ="EditorUi.downloadFiles() " id ="downloadNewButton " class ="secondary ">
515
535
Open a Folder & Download Files
@@ -601,6 +621,15 @@ <h1>Telegram Limits Editor</h1>
601
621
return handle ;
602
622
}
603
623
624
+ static parseIconCodePoints ( iconCodePointsText ) {
625
+ return iconCodePointsText . split ( '\n' ) . reduce ( ( acc , line ) => {
626
+ const [ name , codePoint ] = line . split ( ' ' ) ;
627
+ acc [ name ] = codePoint ;
628
+
629
+ return acc ;
630
+ } , { } ) ;
631
+ }
632
+
604
633
async readFiles ( ) {
605
634
const structureHandle = await this . handle . getDirectoryHandle ( 'data' ) ;
606
635
const structureFile = await structureHandle . getFileHandle ( 'structure.json' ) ;
@@ -628,12 +657,7 @@ <h1>Telegram Limits Editor</h1>
628
657
const iconObjectUrl = URL . createObjectURL ( icon ) ;
629
658
const iconCodePointsText = await iconCodePoints . text ( ) ;
630
659
631
- const iconCodePointsMap = iconCodePointsText . split ( '\n' ) . reduce ( ( acc , line ) => {
632
- const [ name , codePoint ] = line . split ( ' ' ) ;
633
- acc [ name ] = codePoint ;
634
-
635
- return acc ;
636
- } , { } ) ;
660
+ const iconCodePointsMap = WorkDirHandle . parseIconCodePoints ( iconCodePointsText ) ;
637
661
638
662
this . structureFile = structureFile ;
639
663
this . localizationFile = localizationFile ;
@@ -830,6 +854,7 @@ <h1>Telegram Limits Editor</h1>
830
854
static isDirty = false ;
831
855
static contentElement = null ;
832
856
static draggingType = null ;
857
+ static noFsMode = false ;
833
858
834
859
static async openHelp ( source ) {
835
860
alert ( "We're already working on documentation. Until then, for guidance, please contact contributors directly." ) ;
@@ -844,7 +869,10 @@ <h1>Telegram Limits Editor</h1>
844
869
<p>
845
870
<b>Note:</b> We do not accept translations through this form.
846
871
Please go to <a href="https://crowdin.com/project/telegram-limits" target="_blank">Crowdin</a> for translation.
847
- </p>
872
+ </p>
873
+ <p>
874
+ Please group your changes into a single suggestion. Don't submit more often than once-twice a day.
875
+ </p>
848
876
</article>
849
877
<label>
850
878
<span>Description:</span>
@@ -905,12 +933,6 @@ <h1>Telegram Limits Editor</h1>
905
933
}
906
934
907
935
static async check ( ) {
908
- if ( ! ( 'showDirectoryPicker' in window ) ) {
909
- alert ( 'Your browser does not support the File System Access API. ' +
910
- 'Please use a Chromium-based browser, like Google Chrome. Only Desktop version is supported.' ) ;
911
- return ;
912
- }
913
-
914
936
const handle = await WorkDirHandle . checkHandleInIdb ( ) ;
915
937
916
938
if ( handle ) {
@@ -949,6 +971,12 @@ <h1>Telegram Limits Editor</h1>
949
971
}
950
972
951
973
static async newSession ( ) {
974
+ if ( ! ( 'showDirectoryPicker' in window ) ) {
975
+ alert ( 'Your browser does not support the File System Access API. ' +
976
+ 'Please use a Chromium-based browser, like Google Chrome. Only Desktop version is supported.' ) ;
977
+ return ;
978
+ }
979
+
952
980
try {
953
981
this . workDirHandle = new WorkDirHandle ( await WorkDirHandle . createNewHandle ( ) ) ;
954
982
const data = await this . workDirHandle . readFiles ( ) ;
@@ -969,9 +997,61 @@ <h1>Telegram Limits Editor</h1>
969
997
}
970
998
}
971
999
1000
+ static async startSubmission ( ) {
1001
+ const button = document . getElementById ( 'suggestButton' ) ;
1002
+ button . disabled = true ;
1003
+ button . textContent = 'Downloading...' ;
1004
+
1005
+ try {
1006
+ const { structureBlob, localizationBlob, iconBlob, iconCodePointsBlob } = await this . downloadBlobs ( 'master' ) ;
1007
+
1008
+ const structureText = await structureBlob . text ( ) ;
1009
+ const localizationText = await localizationBlob . text ( ) ;
1010
+ const iconCodePointsText = await iconCodePointsBlob . text ( ) ;
972
1011
1012
+ const structure = JSON . parse ( structureText ) ;
1013
+ const localization = JSON . parse ( localizationText ) ;
1014
+ const iconObjectUrl = URL . createObjectURL ( iconBlob ) ;
1015
+ const iconCodePointsMap = WorkDirHandle . parseIconCodePoints ( iconCodePointsText ) ;
1016
+
1017
+ this . noFsMode = true ;
1018
+ this . applyData ( { structure, localization, iconCodePointsMap, iconObjectUrl } ) ;
1019
+ } catch ( e ) {
1020
+ console . error ( e ) ;
1021
+ alert ( 'An error occurred while starting: ' + e . message ) ;
1022
+ } finally {
1023
+ button . disabled = false ;
1024
+ button . textContent = 'Suggest an Edit' ;
1025
+ }
1026
+ }
1027
+
1028
+ static async downloadBlobs ( branchName ) {
1029
+ const urlPrefix = 'https://raw.githubusercontent.com/tginfo/Telegram-Limits/' + branchName ;
1030
+ const structureUrl = `${ urlPrefix } /data/structure.json` ;
1031
+ const localizationUrl = `${ urlPrefix } /localization/en/data.json` ;
1032
+ const iconUrl = `${ urlPrefix } /assets/images/icons.woff2` ;
1033
+ const iconCodePointsUrl = `${ urlPrefix } /assets/images/icons.codepoints` ;
1034
+
1035
+ const structureResponse = await fetch ( structureUrl ) ;
1036
+ const localizationResponse = await fetch ( localizationUrl ) ;
1037
+ const iconResponse = await fetch ( iconUrl ) ;
1038
+ const iconCodePointsResponse = await fetch ( iconCodePointsUrl ) ;
1039
+
1040
+ const structureBlob = await structureResponse . blob ( ) ;
1041
+ const localizationBlob = await localizationResponse . blob ( ) ;
1042
+ const iconBlob = await iconResponse . blob ( ) ;
1043
+ const iconCodePointsBlob = await iconCodePointsResponse . blob ( ) ;
1044
+
1045
+ return { structureBlob, localizationBlob, iconBlob, iconCodePointsBlob } ;
1046
+ }
973
1047
974
1048
static async downloadFiles ( ) {
1049
+ if ( ! ( 'showDirectoryPicker' in window ) ) {
1050
+ alert ( 'Your browser does not support the File System Access API. ' +
1051
+ 'Please use a Chromium-based browser, like Google Chrome. Only Desktop version is supported.' ) ;
1052
+ return ;
1053
+ }
1054
+
975
1055
const button = document . getElementById ( 'downloadNewButton' ) ;
976
1056
try {
977
1057
button . disabled = true ;
@@ -1001,22 +1081,7 @@ <h1>Telegram Limits Editor</h1>
1001
1081
const iconFile = await iconImagesHandle . getFileHandle ( 'icons.woff2' , { create : true } ) ;
1002
1082
const iconCodePointsFile = await iconImagesHandle . getFileHandle ( 'icons.codepoints' , { create : true } ) ;
1003
1083
1004
-
1005
- const urlPrefix = 'https://raw.githubusercontent.com/tginfo/Telegram-Limits/' + branchName ;
1006
- const structureUrl = `${ urlPrefix } /data/structure.json` ;
1007
- const localizationUrl = `${ urlPrefix } /localization/en/data.json` ;
1008
- const iconUrl = `${ urlPrefix } /assets/images/icons.woff2` ;
1009
- const iconCodePointsUrl = `${ urlPrefix } /assets/images/icons.codepoints` ;
1010
-
1011
- const structureResponse = await fetch ( structureUrl ) ;
1012
- const localizationResponse = await fetch ( localizationUrl ) ;
1013
- const iconResponse = await fetch ( iconUrl ) ;
1014
- const iconCodePointsResponse = await fetch ( iconCodePointsUrl ) ;
1015
-
1016
- const structureBlob = await structureResponse . blob ( ) ;
1017
- const localizationBlob = await localizationResponse . blob ( ) ;
1018
- const iconBlob = await iconResponse . blob ( ) ;
1019
- const iconCodePointsBlob = await iconCodePointsResponse . blob ( ) ;
1084
+ const { structureBlob, localizationBlob, iconBlob, iconCodePointsBlob } = await this . downloadBlobs ( branchName ) ;
1020
1085
1021
1086
const structureWritable = await structureFile . createWritable ( ) ;
1022
1087
await structureWritable . write ( structureBlob ) ;
@@ -1102,39 +1167,51 @@ <h1>Telegram Limits Editor</h1>
1102
1167
toolbar . appendChild ( helpButton ) ;
1103
1168
1104
1169
const sendButton = document . createElement ( 'button' ) ;
1105
- sendButton . classList . add ( 'icon' ) ;
1106
- sendButton . classList . add ( 'secondary' ) ;
1107
- sendButton . textContent = 'send' ;
1170
+ if ( ! this . noFsMode ) sendButton . classList . add ( 'for-icon' ) ;
1171
+ if ( ! this . noFsMode ) sendButton . classList . add ( 'secondary' ) ;
1108
1172
sendButton . title = 'Send The Edit to @tginfo' ;
1109
1173
sendButton . addEventListener ( 'click' , ( ) => EditorUi . suggestEdit ( ) ) ;
1110
1174
toolbar . appendChild ( sendButton ) ;
1111
1175
1112
- const saveButton = document . createElement ( 'button' ) ;
1113
- saveButton . classList . add ( 'icon' ) ;
1114
- saveButton . classList . add ( 'secondary' ) ;
1115
- saveButton . textContent = 'save' ;
1116
- saveButton . title = 'Save to Disk' ;
1117
- saveButton . addEventListener ( 'click' , ( ) => this . save ( ) ) ;
1118
- toolbar . appendChild ( saveButton ) ;
1119
-
1120
- const saveStatus = document . createElement ( 'span' ) ;
1121
- saveStatus . id = 'save-status' ;
1122
- toolbar . appendChild ( saveStatus ) ;
1123
-
1124
- this . updateSaveStatus = ( ) => {
1125
- saveStatus . textContent = this . isDirty ? 'Unsaved changes' : 'Saved' ;
1126
- if ( this . isDirty ) {
1127
- saveStatus . classList . add ( 'unsaved' ) ;
1128
- saveButton . classList . remove ( 'secondary' ) ;
1129
- } else {
1130
- saveStatus . classList . remove ( 'unsaved' ) ;
1131
- saveButton . classList . add ( 'secondary' ) ;
1132
- }
1176
+ const sendButtonIcon = document . createElement ( 'span' ) ;
1177
+ sendButtonIcon . classList . add ( 'icon' ) ;
1178
+ sendButtonIcon . textContent = 'send' ;
1179
+ sendButton . appendChild ( sendButtonIcon ) ;
1180
+
1181
+ if ( this . noFsMode ) {
1182
+ const sendButtonLabel = document . createElement ( 'span' ) ;
1183
+ sendButtonLabel . textContent = 'Send suggestion' ;
1184
+ sendButton . appendChild ( sendButtonLabel ) ;
1133
1185
}
1134
1186
1135
- setInterval ( ( ) => {
1136
- this . updateSaveStatus ( ) ;
1137
- } , 1000 ) ;
1187
+ if ( ! this . noFsMode ) {
1188
+ const saveButton = document . createElement ( 'button' ) ;
1189
+ saveButton . classList . add ( 'icon' ) ;
1190
+ saveButton . classList . add ( 'secondary' ) ;
1191
+ saveButton . textContent = 'save' ;
1192
+ saveButton . title = 'Save to Disk' ;
1193
+ saveButton . addEventListener ( 'click' , ( ) => this . save ( ) ) ;
1194
+ toolbar . appendChild ( saveButton ) ;
1195
+
1196
+ const saveStatus = document . createElement ( 'span' ) ;
1197
+ saveStatus . id = 'save-status' ;
1198
+ toolbar . appendChild ( saveStatus ) ;
1199
+
1200
+ this . updateSaveStatus = ( ) => {
1201
+ saveStatus . textContent = this . isDirty ? 'Unsaved changes' : 'Saved' ;
1202
+ if ( this . isDirty ) {
1203
+ saveStatus . classList . add ( 'unsaved' ) ;
1204
+ saveButton . classList . remove ( 'secondary' ) ;
1205
+ } else {
1206
+ saveStatus . classList . remove ( 'unsaved' ) ;
1207
+ saveButton . classList . add ( 'secondary' ) ;
1208
+ }
1209
+ }
1210
+
1211
+ setInterval ( ( ) => {
1212
+ this . updateSaveStatus ( ) ;
1213
+ } , 1000 ) ;
1214
+ }
1138
1215
}
1139
1216
1140
1217
static constructContent ( ) {
0 commit comments