UI updates (#922)

* Fixed download spinner in player component

* Downloads UI is more mobile friendly (#905)

* Code cleanup

* Fixed size of actions in home screen downloads

* Errored downloads now display their stage as "Error" in the UI

* Moved personal settings from about dialog to profile dialog

* Profile dialog can now be opened without logging in/without multi-user mode

* Fixed issue where archive dialog could be accessed from anywhere

* Misc internationalization improvements

* Combined download stage and download progress columns

* Added back loading spinner to download actions

* Adjusted thresholds for consolidating download action buttons

* Implemented virtual scrolling for notifications (helps if many notifications exist)

* Fixed minor console error
This commit is contained in:
Tzahi12345
2023-05-25 21:55:35 -04:00
committed by GitHub
parent ba0de7f95c
commit 2c61260e0f
23 changed files with 651 additions and 534 deletions

View File

@@ -35,36 +35,6 @@
<p>
<ng-container i18n="About bug prefix">Found a bug or have a suggestion?</ng-container>&nbsp;<a [href]="issuesLink" target="_blank"><ng-container i18n="About bug click here">Click here</ng-container></a>&nbsp;<ng-container i18n="About bug suffix">to create an issue!</ng-container>
</p>
<mat-divider></mat-divider>
<div style="margin-top: 10px;">
<h5>Personal settings:</h5>
<mat-form-field>
<mat-label i18n="Sidepanel mode">Sidepanel mode</mat-label>
<mat-select [(ngModel)]="sidepanel_mode" (selectionChange)="sidePanelModeChanged($event.value)">
<mat-option value="over">
Over
</mat-option>
<mat-option value="side">
Side
</mat-option>
</mat-select>
</mat-form-field>
<br/>
<mat-form-field>
<mat-label i18n="File card size">File card size</mat-label>
<mat-select [(ngModel)]="card_size" (selectionChange)="cardSizeOptionChanged($event.value)">
<mat-option value="large">
Large
</mat-option>
<mat-option value="medium">
Medium
</mat-option>
<mat-option value="small">
Small
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</mat-dialog-content>

View File

@@ -16,8 +16,6 @@ export class AboutDialogComponent implements OnInit {
checking_for_updates = true;
current_version_tag = CURRENT_VERSION;
sidepanel_mode = this.postsService.sidepanel_mode;
card_size = this.postsService.card_size;
constructor(public postsService: PostsService) { }
@@ -31,15 +29,4 @@ export class AboutDialogComponent implements OnInit {
this.latestGithubRelease = res;
});
}
sidePanelModeChanged(new_mode) {
localStorage.setItem('sidepanel_mode', new_mode);
this.postsService.sidepanel_mode = new_mode;
}
cardSizeOptionChanged(new_size) {
localStorage.setItem('card_size', new_size);
this.postsService.card_size = new_size;
}
}

View File

@@ -0,0 +1,746 @@
/**
* @author Phil Teare
* using wikipedia data
* Link: https://stackoverflow.com/a/4900304
*/
export const isoLangs = {
'ab': {
'name': 'Abkhaz',
'nativeName': 'аҧсуа'
},
'aa': {
'name': 'Afar',
'nativeName': 'Afaraf'
},
'af': {
'name': 'Afrikaans',
'nativeName': 'Afrikaans'
},
'ak': {
'name': 'Akan',
'nativeName': 'Akan'
},
'sq': {
'name': 'Albanian',
'nativeName': 'Shqip'
},
'am': {
'name': 'Amharic',
'nativeName': 'አማርኛ'
},
'ar': {
'name': 'Arabic',
'nativeName': 'العربية'
},
'an': {
'name': 'Aragonese',
'nativeName': 'Aragonés'
},
'hy': {
'name': 'Armenian',
'nativeName': 'Հայերեն'
},
'as': {
'name': 'Assamese',
'nativeName': 'অসমীয়া'
},
'av': {
'name': 'Avaric',
'nativeName': 'авар мацӀ, магӀарул мацӀ'
},
'ae': {
'name': 'Avestan',
'nativeName': 'avesta'
},
'ay': {
'name': 'Aymara',
'nativeName': 'aymar aru'
},
'az': {
'name': 'Azerbaijani',
'nativeName': 'azərbaycan dili'
},
'bm': {
'name': 'Bambara',
'nativeName': 'bamanankan'
},
'ba': {
'name': 'Bashkir',
'nativeName': 'башҡорт теле'
},
'eu': {
'name': 'Basque',
'nativeName': 'euskara, euskera'
},
'be': {
'name': 'Belarusian',
'nativeName': 'Беларуская'
},
'bn': {
'name': 'Bengali',
'nativeName': 'বাংলা'
},
'bh': {
'name': 'Bihari',
'nativeName': 'भोजपुरी'
},
'bi': {
'name': 'Bislama',
'nativeName': 'Bislama'
},
'bs': {
'name': 'Bosnian',
'nativeName': 'bosanski jezik'
},
'br': {
'name': 'Breton',
'nativeName': 'brezhoneg'
},
'bg': {
'name': 'Bulgarian',
'nativeName': 'български език'
},
'my': {
'name': 'Burmese',
'nativeName': 'ဗမာစာ'
},
'ca': {
'name': 'Catalan',
'nativeName': 'Català'
},
'ch': {
'name': 'Chamorro',
'nativeName': 'Chamoru'
},
'ce': {
'name': 'Chechen',
'nativeName': 'нохчийн мотт'
},
'ny': {
'name': 'Chichewa; Chewa; Nyanja',
'nativeName': 'chiCheŵa, chinyanja'
},
'zh': {
'name': 'Chinese',
'nativeName': '中文 (Zhōngwén), 汉语, 漢語',
'ngID': 'zh'
},
'cv': {
'name': 'Chuvash',
'nativeName': 'чӑваш чӗлхи'
},
'kw': {
'name': 'Cornish',
'nativeName': 'Kernewek'
},
'co': {
'name': 'Corsican',
'nativeName': 'corsu, lingua corsa'
},
'cr': {
'name': 'Cree',
'nativeName': 'ᓀᐦᐃᔭᐍᐏᐣ'
},
'hr': {
'name': 'Croatian',
'nativeName': 'hrvatski'
},
'cs': {
'name': 'Czech',
'nativeName': 'česky, čeština'
},
'da': {
'name': 'Danish',
'nativeName': 'dansk'
},
'dv': {
'name': 'Divehi; Dhivehi; Maldivian;',
'nativeName': 'ދިވެހި'
},
'nl': {
'name': 'Dutch',
'nativeName': 'Nederlands'
},
'en': {
'name': 'English',
'nativeName': 'English',
'ngID': 'en-US'
},
'en-GB': {
'name': 'British English',
'nativeName': 'British English',
'ngID': 'en-GB'
},
'eo': {
'name': 'Esperanto',
'nativeName': 'Esperanto'
},
'et': {
'name': 'Estonian',
'nativeName': 'eesti, eesti keel'
},
'ee': {
'name': 'Ewe',
'nativeName': 'Eʋegbe'
},
'fo': {
'name': 'Faroese',
'nativeName': 'føroyskt'
},
'fj': {
'name': 'Fijian',
'nativeName': 'vosa Vakaviti'
},
'fi': {
'name': 'Finnish',
'nativeName': 'suomi, suomen kieli'
},
'fr': {
'name': 'French',
'nativeName': 'français',
'ngID': 'fr'
},
'ff': {
'name': 'Fula; Fulah; Pulaar; Pular',
'nativeName': 'Fulfulde, Pulaar, Pular'
},
'gl': {
'name': 'Galician',
'nativeName': 'Galego'
},
'ka': {
'name': 'Georgian',
'nativeName': 'ქართული'
},
'de': {
'name': 'German',
'nativeName': 'Deutsch',
'ngID': 'de'
},
'el': {
'name': 'Greek, Modern',
'nativeName': 'Ελληνικά'
},
'gn': {
'name': 'Guaraní',
'nativeName': 'Avañeẽ'
},
'gu': {
'name': 'Gujarati',
'nativeName': 'ગુજરાતી'
},
'ht': {
'name': 'Haitian; Haitian Creole',
'nativeName': 'Kreyòl ayisyen'
},
'ha': {
'name': 'Hausa',
'nativeName': 'Hausa, هَوُسَ'
},
'he': {
'name': 'Hebrew (modern)',
'nativeName': 'עברית'
},
'hz': {
'name': 'Herero',
'nativeName': 'Otjiherero'
},
'hi': {
'name': 'Hindi',
'nativeName': 'हिन्दी, हिंदी'
},
'ho': {
'name': 'Hiri Motu',
'nativeName': 'Hiri Motu'
},
'hu': {
'name': 'Hungarian',
'nativeName': 'Magyar'
},
'ia': {
'name': 'Interlingua',
'nativeName': 'Interlingua'
},
'id': {
'name': 'Indonesian',
'nativeName': 'Bahasa Indonesia'
},
'ie': {
'name': 'Interlingue',
'nativeName': 'Originally called Occidental; then Interlingue after WWII'
},
'ga': {
'name': 'Irish',
'nativeName': 'Gaeilge'
},
'ig': {
'name': 'Igbo',
'nativeName': 'Asụsụ Igbo'
},
'ik': {
'name': 'Inupiaq',
'nativeName': 'Iñupiaq, Iñupiatun'
},
'io': {
'name': 'Ido',
'nativeName': 'Ido'
},
'is': {
'name': 'Icelandic',
'nativeName': 'Íslenska'
},
'it': {
'name': 'Italian',
'nativeName': 'Italiano'
},
'iu': {
'name': 'Inuktitut',
'nativeName': 'ᐃᓄᒃᑎᑐᑦ'
},
'ja': {
'name': 'Japanese',
'nativeName': '日本語 (にほんご/にっぽんご)'
},
'jv': {
'name': 'Javanese',
'nativeName': 'basa Jawa'
},
'kl': {
'name': 'Kalaallisut, Greenlandic',
'nativeName': 'kalaallisut, kalaallit oqaasii'
},
'kn': {
'name': 'Kannada',
'nativeName': 'ಕನ್ನಡ'
},
'kr': {
'name': 'Kanuri',
'nativeName': 'Kanuri'
},
'ks': {
'name': 'Kashmiri',
'nativeName': 'कश्मीरी, كشميري‎'
},
'kk': {
'name': 'Kazakh',
'nativeName': 'Қазақ тілі'
},
'km': {
'name': 'Khmer',
'nativeName': 'ភាសាខ្មែរ'
},
'ki': {
'name': 'Kikuyu, Gikuyu',
'nativeName': 'Gĩkũyũ'
},
'rw': {
'name': 'Kinyarwanda',
'nativeName': 'Ikinyarwanda'
},
'ky': {
'name': 'Kirghiz, Kyrgyz',
'nativeName': 'кыргыз тили'
},
'kv': {
'name': 'Komi',
'nativeName': 'коми кыв'
},
'kg': {
'name': 'Kongo',
'nativeName': 'KiKongo'
},
'ko': {
'name': 'Korean',
'nativeName': '한국어 (韓國語), 조선말 (朝鮮語)'
},
'ku': {
'name': 'Kurdish',
'nativeName': 'Kurdî, كوردی‎'
},
'kj': {
'name': 'Kwanyama, Kuanyama',
'nativeName': 'Kuanyama'
},
'la': {
'name': 'Latin',
'nativeName': 'latine, lingua latina'
},
'lb': {
'name': 'Luxembourgish, Letzeburgesch',
'nativeName': 'Lëtzebuergesch'
},
'lg': {
'name': 'Luganda',
'nativeName': 'Luganda'
},
'li': {
'name': 'Limburgish, Limburgan, Limburger',
'nativeName': 'Limburgs'
},
'ln': {
'name': 'Lingala',
'nativeName': 'Lingála'
},
'lo': {
'name': 'Lao',
'nativeName': 'ພາສາລາວ'
},
'lt': {
'name': 'Lithuanian',
'nativeName': 'lietuvių kalba'
},
'lu': {
'name': 'Luba-Katanga',
'nativeName': ''
},
'lv': {
'name': 'Latvian',
'nativeName': 'latviešu valoda'
},
'gv': {
'name': 'Manx',
'nativeName': 'Gaelg, Gailck'
},
'mk': {
'name': 'Macedonian',
'nativeName': 'македонски јазик'
},
'mg': {
'name': 'Malagasy',
'nativeName': 'Malagasy fiteny'
},
'ms': {
'name': 'Malay',
'nativeName': 'bahasa Melayu, بهاس ملايو‎'
},
'ml': {
'name': 'Malayalam',
'nativeName': 'മലയാളം'
},
'mt': {
'name': 'Maltese',
'nativeName': 'Malti'
},
'mi': {
'name': 'Māori',
'nativeName': 'te reo Māori'
},
'mr': {
'name': 'Marathi (Marāṭhī)',
'nativeName': 'मराठी'
},
'mh': {
'name': 'Marshallese',
'nativeName': 'Kajin M̧ajeļ'
},
'mn': {
'name': 'Mongolian',
'nativeName': 'монгол'
},
'na': {
'name': 'Nauru',
'nativeName': 'Ekakairũ Naoero'
},
'nv': {
'name': 'Navajo, Navaho',
'nativeName': 'Diné bizaad, Dinékʼehǰí'
},
'nb-NO': {
'name': 'Norwegian Bokmål',
'nativeName': 'Norsk bokmål',
'ngID': 'nb'
},
'nd': {
'name': 'North Ndebele',
'nativeName': 'isiNdebele'
},
'ne': {
'name': 'Nepali',
'nativeName': 'नेपाली'
},
'ng': {
'name': 'Ndonga',
'nativeName': 'Owambo'
},
'nn': {
'name': 'Norwegian Nynorsk',
'nativeName': 'Norsk nynorsk'
},
'no': {
'name': 'Norwegian',
'nativeName': 'Norsk'
},
'ii': {
'name': 'Nuosu',
'nativeName': 'ꆈꌠ꒿ Nuosuhxop'
},
'nr': {
'name': 'South Ndebele',
'nativeName': 'isiNdebele'
},
'oc': {
'name': 'Occitan',
'nativeName': 'Occitan'
},
'oj': {
'name': 'Ojibwe, Ojibwa',
'nativeName': 'ᐊᓂᔑᓈᐯᒧᐎᓐ'
},
'cu': {
'name': 'Old Church Slavonic, Church Slavic, Church Slavonic, Old Bulgarian, Old Slavonic',
'nativeName': 'ѩзыкъ словѣньскъ'
},
'om': {
'name': 'Oromo',
'nativeName': 'Afaan Oromoo'
},
'or': {
'name': 'Oriya',
'nativeName': 'ଓଡ଼ିଆ'
},
'os': {
'name': 'Ossetian, Ossetic',
'nativeName': 'ирон æвзаг'
},
'pa': {
'name': 'Panjabi, Punjabi',
'nativeName': 'ਪੰਜਾਬੀ, پنجابی‎'
},
'pi': {
'name': 'Pāli',
'nativeName': 'पाऴि'
},
'fa': {
'name': 'Persian',
'nativeName': 'فارسی'
},
'pl': {
'name': 'Polish',
'nativeName': 'polski'
},
'ps': {
'name': 'Pashto, Pushto',
'nativeName': 'پښتو'
},
'pt': {
'name': 'Portuguese',
'nativeName': 'Português'
},
'qu': {
'name': 'Quechua',
'nativeName': 'Runa Simi, Kichwa'
},
'rm': {
'name': 'Romansh',
'nativeName': 'rumantsch grischun'
},
'rn': {
'name': 'Kirundi',
'nativeName': 'kiRundi'
},
'ro': {
'name': 'Romanian, Moldavian, Moldovan',
'nativeName': 'română'
},
'ru': {
'name': 'Russian',
'nativeName': 'русский язык'
},
'sa': {
'name': 'Sanskrit (Saṁskṛta)',
'nativeName': 'संस्कृतम्'
},
'sc': {
'name': 'Sardinian',
'nativeName': 'sardu'
},
'sd': {
'name': 'Sindhi',
'nativeName': 'सिन्धी, سنڌي، سندھی‎'
},
'se': {
'name': 'Northern Sami',
'nativeName': 'Davvisámegiella'
},
'sm': {
'name': 'Samoan',
'nativeName': 'gagana faa Samoa'
},
'sg': {
'name': 'Sango',
'nativeName': 'yângâ tî sängö'
},
'sr': {
'name': 'Serbian',
'nativeName': 'српски језик'
},
'gd': {
'name': 'Scottish Gaelic; Gaelic',
'nativeName': 'Gàidhlig'
},
'sn': {
'name': 'Shona',
'nativeName': 'chiShona'
},
'si': {
'name': 'Sinhala, Sinhalese',
'nativeName': 'සිංහල'
},
'sk': {
'name': 'Slovak',
'nativeName': 'slovenčina'
},
'sl': {
'name': 'Slovene',
'nativeName': 'slovenščina'
},
'so': {
'name': 'Somali',
'nativeName': 'Soomaaliga, af Soomaali'
},
'st': {
'name': 'Southern Sotho',
'nativeName': 'Sesotho'
},
'es': {
'name': 'Spanish; Castilian',
'nativeName': 'español',
'ngID': 'es'
},
'su': {
'name': 'Sundanese',
'nativeName': 'Basa Sunda'
},
'sw': {
'name': 'Swahili',
'nativeName': 'Kiswahili'
},
'ss': {
'name': 'Swati',
'nativeName': 'SiSwati'
},
'sv': {
'name': 'Swedish',
'nativeName': 'svenska'
},
'ta': {
'name': 'Tamil',
'nativeName': 'தமிழ்'
},
'te': {
'name': 'Telugu',
'nativeName': 'తెలుగు'
},
'tg': {
'name': 'Tajik',
'nativeName': 'тоҷикӣ, toğikī, تاجیکی‎'
},
'th': {
'name': 'Thai',
'nativeName': 'ไทย'
},
'ti': {
'name': 'Tigrinya',
'nativeName': 'ትግርኛ'
},
'bo': {
'name': 'Tibetan Standard, Tibetan, Central',
'nativeName': 'བོད་ཡིག'
},
'tk': {
'name': 'Turkmen',
'nativeName': 'Türkmen, Түркмен'
},
'tl': {
'name': 'Tagalog',
'nativeName': 'Wikang Tagalog, ᜏᜒᜃᜅ᜔ ᜆᜄᜎᜓᜄ᜔'
},
'tn': {
'name': 'Tswana',
'nativeName': 'Setswana'
},
'to': {
'name': 'Tonga (Tonga Islands)',
'nativeName': 'faka Tonga'
},
'tr': {
'name': 'Turkish',
'nativeName': 'Türkçe'
},
'ts': {
'name': 'Tsonga',
'nativeName': 'Xitsonga'
},
'tt': {
'name': 'Tatar',
'nativeName': 'татарча, tatarça, تاتارچا‎'
},
'tw': {
'name': 'Twi',
'nativeName': 'Twi'
},
'ty': {
'name': 'Tahitian',
'nativeName': 'Reo Tahiti'
},
'ug': {
'name': 'Uighur, Uyghur',
'nativeName': 'Uyƣurqə, ئۇيغۇرچە‎'
},
'uk': {
'name': 'Ukrainian',
'nativeName': 'українська'
},
'ur': {
'name': 'Urdu',
'nativeName': 'اردو'
},
'uz': {
'name': 'Uzbek',
'nativeName': 'zbek, Ўзбек, أۇزبېك‎'
},
've': {
'name': 'Venda',
'nativeName': 'Tshivenḓa'
},
'vi': {
'name': 'Vietnamese',
'nativeName': 'Tiếng Việt'
},
'vo': {
'name': 'Volapük',
'nativeName': 'Volapük'
},
'wa': {
'name': 'Walloon',
'nativeName': 'Walon'
},
'cy': {
'name': 'Welsh',
'nativeName': 'Cymraeg'
},
'wo': {
'name': 'Wolof',
'nativeName': 'Wollof'
},
'fy': {
'name': 'Western Frisian',
'nativeName': 'Frysk'
},
'xh': {
'name': 'Xhosa',
'nativeName': 'isiXhosa'
},
'yi': {
'name': 'Yiddish',
'nativeName': 'ייִדיש'
},
'yo': {
'name': 'Yoruba',
'nativeName': 'Yorùbá'
},
'za': {
'name': 'Zhuang, Chuang',
'nativeName': 'Saɯ cueŋƅ, Saw cuengh'
}
};

View File

@@ -13,19 +13,52 @@
</div>
<div style="margin-top: 20px;">
</div>
<mat-divider style="margin-bottom: 20px"></mat-divider>
</div>
<div *ngIf="!postsService.isLoggedIn || !postsService.user">
<h5><mat-icon>warn</mat-icon><ng-container i18n="Not logged in notification">You are not logged in.</ng-container></h5>
<button (click)="loginClicked()" mat-raised-button color="primary"><ng-container i18n="Login">Login</ng-container></button>
</div>
<mat-form-field color="accent">
<mat-label><ng-container i18n="Language select label">Language</ng-container></mat-label>
<mat-select (selectionChange)="localeSelectChanged($event.value)" [(value)]="initialLocale">
<mat-option *ngFor="let locale of supported_locales" [value]="locale">
<ng-container *ngIf="all_locales[locale]">
{{all_locales[locale]['nativeName']}}
</ng-container>
</mat-option>
</mat-select>
</mat-form-field>
<br/>
<mat-form-field>
<mat-label i18n="Sidepanel mode">Sidepanel mode</mat-label>
<mat-select [(ngModel)]="sidepanel_mode" (selectionChange)="sidePanelModeChanged($event.value)">
<mat-option i18n="Over" value="over">
Over
</mat-option>
<mat-option i18n="Side" value="side">
Side
</mat-option>
</mat-select>
</mat-form-field>
<br/>
<mat-form-field>
<mat-label i18n="File card size">File card size</mat-label>
<mat-select [(ngModel)]="card_size" (selectionChange)="cardSizeOptionChanged($event.value)">
<mat-option i18n="Large" value="large">
Large
</mat-option>
<mat-option i18n="Medium" value="medium">
Medium
</mat-option>
<mat-option i18n="Small" value="small">
Small
</mat-option>
</mat-select>
</mat-form-field>
</mat-dialog-content>
<mat-dialog-actions>
<div style="width: 100%">
<div style="position: relative">
<button mat-stroked-button mat-dialog-close color="primary"><ng-container i18n="Close">Close</ng-container></button>
<button style="position: absolute; right: 0px;" (click)="logoutClicked()" mat-stroked-button color="warn"><ng-container i18n="Logout">Logout</ng-container></button>
<button *ngIf="postsService.isLoggedIn" style="position: absolute; right: 0px;" (click)="logoutClicked()" mat-stroked-button color="warn"><ng-container i18n="Logout">Logout</ng-container></button>
</div>
</div>
</mat-dialog-actions>

View File

@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { PostsService } from 'app/posts.services';
import { Router } from '@angular/router';
import { MatDialogRef } from '@angular/material/dialog';
import { isoLangs } from './locales_list';
@Component({
selector: 'app-user-profile-dialog',
@@ -10,9 +11,24 @@ import { MatDialogRef } from '@angular/material/dialog';
})
export class UserProfileDialogComponent implements OnInit {
all_locales = isoLangs;
supported_locales = ['en', 'es', 'de', 'fr', 'nl', 'pt', 'it', 'ca', 'cs', 'nb', 'ru', 'zh', 'ko', 'id', 'en-GB'];
initialLocale = localStorage.getItem('locale');
sidepanel_mode = this.postsService.sidepanel_mode;
card_size = this.postsService.card_size;
constructor(public postsService: PostsService, private router: Router, public dialogRef: MatDialogRef<UserProfileDialogComponent>) { }
ngOnInit(): void {
this.postsService.getSupportedLocales().subscribe(res => {
if (res && res['supported_locales']) {
this.supported_locales = ['en', 'en-GB']; // required
this.supported_locales = this.supported_locales.concat(res['supported_locales']);
}
}, err => {
console.error(`Failed to retrieve list of supported languages! You may need to run: 'node src/postbuild.mjs'. Error below:`);
console.error(err);
});
}
loginClicked() {
@@ -25,4 +41,19 @@ export class UserProfileDialogComponent implements OnInit {
this.dialogRef.close();
}
localeSelectChanged(new_val: string): void {
localStorage.setItem('locale', new_val);
this.postsService.openSnackBar($localize`Language successfully changed! Reload to update the page.`)
}
sidePanelModeChanged(new_mode) {
localStorage.setItem('sidepanel_mode', new_mode);
this.postsService.sidepanel_mode = new_mode;
}
cardSizeOptionChanged(new_size) {
localStorage.setItem('card_size', new_size);
this.postsService.card_size = new_size;
}
}