diff options
-rw-r--r-- | README.md | 18 | ||||
-rwxr-xr-x | install.sh | 2 | ||||
-rw-r--r-- | server/migrations/2019-12-09-060754_add_lang/down.sql | 1 | ||||
-rw-r--r-- | server/migrations/2019-12-09-060754_add_lang/up.sql | 1 | ||||
-rw-r--r-- | server/src/api/user.rs | 6 | ||||
-rw-r--r-- | server/src/apub.rs | 1 | ||||
-rw-r--r-- | server/src/db/comment.rs | 1 | ||||
-rw-r--r-- | server/src/db/comment_view.rs | 1 | ||||
-rw-r--r-- | server/src/db/community.rs | 1 | ||||
-rw-r--r-- | server/src/db/moderator.rs | 2 | ||||
-rw-r--r-- | server/src/db/password_reset_request.rs | 1 | ||||
-rw-r--r-- | server/src/db/post.rs | 1 | ||||
-rw-r--r-- | server/src/db/post_view.rs | 1 | ||||
-rw-r--r-- | server/src/db/user.rs | 6 | ||||
-rw-r--r-- | server/src/db/user_mention.rs | 2 | ||||
-rw-r--r-- | server/src/schema.rs | 1 | ||||
-rw-r--r-- | ui/src/components/user.tsx | 35 | ||||
-rw-r--r-- | ui/src/interfaces.ts | 2 | ||||
-rw-r--r-- | ui/src/translations/en.ts | 2 | ||||
-rw-r--r-- | ui/src/utils.ts | 39 |
20 files changed, 107 insertions, 17 deletions
@@ -247,15 +247,15 @@ If you'd like to add translations, take a look a look at the [English translatio lang | done | missing --- | --- | --- -de | 79% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,subscribed,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,expires,recent_comments,nsfw,show_nsfw,theme,crypto,monero,joined,by,to,transfer_community,transfer_site,are_you_sure,yes,no -eo | 87% | number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,theme,are_you_sure,yes,no -es | 96% | archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup -fr | 96% | archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup -it | 97% | archive_link,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup -nl | 89% | preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,theme -ru | 83% | cross_posts,cross_post,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,recent_comments,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no -sv | 96% | archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup -zh | 81% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,recent_comments,nsfw,show_nsfw,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no +de | 78% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,subscribed,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,expires,language,browser_default,recent_comments,nsfw,show_nsfw,theme,crypto,monero,joined,by,to,transfer_community,transfer_site,are_you_sure,yes,no +eo | 86% | number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,theme,are_you_sure,yes,no +es | 95% | archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default +fr | 95% | archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default +it | 96% | archive_link,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default +nl | 88% | preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,theme +ru | 82% | cross_posts,cross_post,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,recent_comments,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no +sv | 95% | archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default +zh | 80% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,recent_comments,nsfw,show_nsfw,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no If you'd like to update this report, run: @@ -1,7 +1,7 @@ #!/bin/sh set -e -export DATABASE_URL=postgres://rrr:rrr@localhost/rrr +export DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy export JWT_SECRET=changeme export HOSTNAME=rrr diff --git a/server/migrations/2019-12-09-060754_add_lang/down.sql b/server/migrations/2019-12-09-060754_add_lang/down.sql new file mode 100644 index 00000000..c1335599 --- /dev/null +++ b/server/migrations/2019-12-09-060754_add_lang/down.sql @@ -0,0 +1 @@ +alter table user_ drop column lang; diff --git a/server/migrations/2019-12-09-060754_add_lang/up.sql b/server/migrations/2019-12-09-060754_add_lang/up.sql new file mode 100644 index 00000000..98a72ad9 --- /dev/null +++ b/server/migrations/2019-12-09-060754_add_lang/up.sql @@ -0,0 +1 @@ +alter table user_ add column lang varchar(20) default 'browser' not null; diff --git a/server/src/api/user.rs b/server/src/api/user.rs index 7f7af813..bc51c8e9 100644 --- a/server/src/api/user.rs +++ b/server/src/api/user.rs @@ -25,6 +25,7 @@ pub struct SaveUserSettings { theme: String, default_sort_type: i16, default_listing_type: i16, + lang: String, auth: String, } @@ -220,6 +221,7 @@ impl Perform<LoginResponse> for Oper<Register> { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; // Create the user @@ -313,6 +315,7 @@ impl Perform<LoginResponse> for Oper<SaveUserSettings> { theme: data.theme.to_owned(), default_sort_type: data.default_sort_type, default_listing_type: data.default_listing_type, + lang: data.lang.to_owned(), }; let updated_user = match User_::update(&conn, user_id, &user_form) { @@ -445,6 +448,7 @@ impl Perform<AddAdminResponse> for Oper<AddAdmin> { theme: read_user.theme, default_sort_type: read_user.default_sort_type, default_listing_type: read_user.default_listing_type, + lang: read_user.lang, }; match User_::update(&conn, data.user_id, &user_form) { @@ -506,6 +510,7 @@ impl Perform<BanUserResponse> for Oper<BanUser> { theme: read_user.theme, default_sort_type: read_user.default_sort_type, default_listing_type: read_user.default_listing_type, + lang: read_user.lang, }; match User_::update(&conn, data.user_id, &user_form) { @@ -842,6 +847,7 @@ impl Perform<LoginResponse> for Oper<PasswordChange> { theme: read_user.theme, default_sort_type: read_user.default_sort_type, default_listing_type: read_user.default_listing_type, + lang: read_user.lang, }; let updated_user = match User_::update_password(&conn, user_id, &user_form) { diff --git a/server/src/apub.rs b/server/src/apub.rs index 3c7202b2..66878d37 100644 --- a/server/src/apub.rs +++ b/server/src/apub.rs @@ -76,6 +76,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let person = expected_user.person(); diff --git a/server/src/db/comment.rs b/server/src/db/comment.rs index 64532b83..b7bd562d 100644 --- a/server/src/db/comment.rs +++ b/server/src/db/comment.rs @@ -181,6 +181,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let inserted_user = User_::create(&conn, &new_user).unwrap(); diff --git a/server/src/db/comment_view.rs b/server/src/db/comment_view.rs index dd53ddca..54c43b93 100644 --- a/server/src/db/comment_view.rs +++ b/server/src/db/comment_view.rs @@ -415,6 +415,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let inserted_user = User_::create(&conn, &new_user).unwrap(); diff --git a/server/src/db/community.rs b/server/src/db/community.rs index bfc6089b..95469075 100644 --- a/server/src/db/community.rs +++ b/server/src/db/community.rs @@ -267,6 +267,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let inserted_user = User_::create(&conn, &new_user).unwrap(); diff --git a/server/src/db/moderator.rs b/server/src/db/moderator.rs index b04c6c62..22547ca4 100644 --- a/server/src/db/moderator.rs +++ b/server/src/db/moderator.rs @@ -449,6 +449,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let inserted_mod = User_::create(&conn, &new_mod).unwrap(); @@ -466,6 +467,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let inserted_user = User_::create(&conn, &new_user).unwrap(); diff --git a/server/src/db/password_reset_request.rs b/server/src/db/password_reset_request.rs index 265945df..8c65b4c0 100644 --- a/server/src/db/password_reset_request.rs +++ b/server/src/db/password_reset_request.rs @@ -92,6 +92,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let inserted_user = User_::create(&conn, &new_user).unwrap(); diff --git a/server/src/db/post.rs b/server/src/db/post.rs index f185bd75..96ae31db 100644 --- a/server/src/db/post.rs +++ b/server/src/db/post.rs @@ -194,6 +194,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let inserted_user = User_::create(&conn, &new_user).unwrap(); diff --git a/server/src/db/post_view.rs b/server/src/db/post_view.rs index 7a589738..4fcd8e47 100644 --- a/server/src/db/post_view.rs +++ b/server/src/db/post_view.rs @@ -345,6 +345,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let inserted_user = User_::create(&conn, &new_user).unwrap(); diff --git a/server/src/db/user.rs b/server/src/db/user.rs index 064bff39..3d3865e8 100644 --- a/server/src/db/user.rs +++ b/server/src/db/user.rs @@ -23,6 +23,7 @@ pub struct User_ { pub theme: String, pub default_sort_type: i16, pub default_listing_type: i16, + pub lang: String, } #[derive(Insertable, AsChangeset, Clone)] @@ -40,6 +41,7 @@ pub struct UserForm { pub theme: String, pub default_sort_type: i16, pub default_listing_type: i16, + pub lang: String, } impl Crud<UserForm> for User_ { @@ -96,6 +98,7 @@ pub struct Claims { pub theme: String, pub default_sort_type: i16, pub default_listing_type: i16, + pub lang: String, } impl Claims { @@ -119,6 +122,7 @@ impl User_ { theme: self.theme.to_owned(), default_sort_type: self.default_sort_type, default_listing_type: self.default_listing_type, + lang: self.lang.to_owned(), }; encode( &Header::default(), @@ -175,6 +179,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let inserted_user = User_::create(&conn, &new_user).unwrap(); @@ -195,6 +200,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let read_user = User_::read(&conn, inserted_user.id).unwrap(); diff --git a/server/src/db/user_mention.rs b/server/src/db/user_mention.rs index 668d28fc..7eb4d486 100644 --- a/server/src/db/user_mention.rs +++ b/server/src/db/user_mention.rs @@ -75,6 +75,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let inserted_user = User_::create(&conn, &new_user).unwrap(); @@ -92,6 +93,7 @@ mod tests { theme: "darkly".into(), default_sort_type: SortType::Hot as i16, default_listing_type: ListingType::Subscribed as i16, + lang: "browser".into(), }; let inserted_recipient = User_::create(&conn, &recipient_form).unwrap(); diff --git a/server/src/schema.rs b/server/src/schema.rs index 5fc70953..bd73aabf 100644 --- a/server/src/schema.rs +++ b/server/src/schema.rs @@ -266,6 +266,7 @@ table! { theme -> Varchar, default_sort_type -> Int2, default_listing_type -> Int2, + lang -> Varchar, } } diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx index 0aba995f..bf77d4b7 100644 --- a/ui/src/components/user.tsx +++ b/ui/src/components/user.tsx @@ -27,6 +27,7 @@ import { capitalizeFirstLetter, themes, setTheme, + languages, } from '../utils'; import { PostListing } from './post-listing'; import { SortSelect } from './sort-select'; @@ -94,6 +95,7 @@ export class User extends Component<any, UserState> { theme: null, default_sort_type: null, default_listing_type: null, + lang: null, auth: null, }, userSettingsLoading: null, @@ -423,6 +425,32 @@ export class User extends Component<any, UserState> { <div class="form-group"> <div class="col-12"> <label> + <T i18nKey="language">#</T> + </label> + <select + value={this.state.userSettingsForm.lang} + onChange={linkEvent( + this, + this.handleUserSettingsLangChange + )} + class="ml-2 custom-select custom-select-sm w-auto" + > + <option disabled> + <T i18nKey="language">#</T> + </option> + <option value="browser"> + <T i18nKey="browser_default">#</T> + </option> + <option disabled>──</option> + {languages.map(lang => ( + <option value={lang.code}>{lang.name}</option> + ))} + </select> + </div> + </div> + <div class="form-group"> + <div class="col-12"> + <label> <T i18nKey="theme">#</T> </label> <select @@ -693,6 +721,12 @@ export class User extends Component<any, UserState> { i.setState(i.state); } + handleUserSettingsLangChange(i: User, event: any) { + i.state.userSettingsForm.lang = event.target.value; + i18n.changeLanguage(i.state.userSettingsForm.lang); + i.setState(i.state); + } + handleUserSettingsSortTypeChange(val: SortType) { this.state.userSettingsForm.default_sort_type = val; this.setState(this.state); @@ -762,6 +796,7 @@ export class User extends Component<any, UserState> { UserService.Instance.user.default_sort_type; this.state.userSettingsForm.default_listing_type = UserService.Instance.user.default_listing_type; + this.state.userSettingsForm.lang = UserService.Instance.user.lang; } document.title = `/u/${this.state.user.name} - ${WebSocketService.Instance.site.name}`; window.scrollTo(0, 0); diff --git a/ui/src/interfaces.ts b/ui/src/interfaces.ts index 9cd9bef4..f327202a 100644 --- a/ui/src/interfaces.ts +++ b/ui/src/interfaces.ts @@ -79,6 +79,7 @@ export interface User { theme: string; default_sort_type: SortType; default_listing_type: ListingType; + lang: string; } export interface UserView { @@ -469,6 +470,7 @@ export interface UserSettingsForm { theme: string; default_sort_type: SortType; default_listing_type: ListingType; + lang: string; auth: string; } diff --git a/ui/src/translations/en.ts b/ui/src/translations/en.ts index e20ba40a..ce5fcdcc 100644 --- a/ui/src/translations/en.ts +++ b/ui/src/translations/en.ts @@ -125,6 +125,8 @@ export const en = { email: 'Email', optional: 'Optional', expires: 'Expires', + language: 'Language', + browser_default: 'Browser Default', url: 'URL', body: 'Body', copy_suggested_title: 'copy suggested title: {{title}}', diff --git a/ui/src/utils.ts b/ui/src/utils.ts index 2cf80d14..1bbda3aa 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -16,6 +16,7 @@ import { ListingType, SearchType, } from './interfaces'; +import { UserService } from './services/UserService'; import * as markdown_it from 'markdown-it'; import * as markdownitEmoji from 'markdown-it-emoji/light'; import * as markdown_it_container from 'markdown-it-container'; @@ -240,16 +241,32 @@ export function debounce( }; } +export const languages = [ + { code: 'en', name: 'English' }, + { code: 'eo', name: 'Esperanto' }, + { code: 'es', name: 'Español' }, + { code: 'de', name: 'Deutsch' }, + { code: 'zh', name: '中文' }, + { code: 'fr', name: 'Français' }, + { code: 'sv', name: 'Svenska' }, + { code: 'ru', name: 'Русский' }, + { code: 'nl', name: 'Nederlands' }, + { code: 'it', name: 'Italiano' }, +]; + export function getLanguage(): string { - return navigator.language || navigator.userLanguage; + let user = UserService.Instance.user; + let lang = user && user.lang ? user.lang : 'browser'; + + if (lang == 'browser') { + return getBrowserLanguage(); + } else { + return lang; + } } -export function objectFlip(obj: any) { - const ret = {}; - Object.keys(obj).forEach(key => { - ret[obj[key]] = key; - }); - return ret; +export function getBrowserLanguage(): string { + return navigator.language || navigator.userLanguage; } export function getMomentLanguage(): string { @@ -313,3 +330,11 @@ export function setTheme(theme: string = 'darkly') { } document.getElementById(theme).removeAttribute('disabled'); } + +export function objectFlip(obj: any) { + const ret = {}; + Object.keys(obj).forEach(key => { + ret[obj[key]] = key; + }); + return ret; +} |