diff --git a/src/UI/PuterDialog.js b/src/UI/PuterDialog.js index 648ad0c2..21ffc822 100644 --- a/src/UI/PuterDialog.js +++ b/src/UI/PuterDialog.js @@ -26,11 +26,11 @@ async function PuterDialog(options) {

This website uses Puter to bring you safe, secure, and private AI and Cloud features.

- - + +
-

Powered by Puter.js

-

By clicking 'Continue' you agree to Puter's Terms of Service and Privacy Policy.

+

${i18n('powered_by_puter_js')}

+

${i18n('tos_fineprint')}

`; const el_window = await UIWindow({ diff --git a/src/UI/UIDesktop.js b/src/UI/UIDesktop.js index c25b69fd..db791a29 100644 --- a/src/UI/UIDesktop.js +++ b/src/UI/UIDesktop.js @@ -622,10 +622,10 @@ async function UIDesktop(options){ // Sort by // ------------------------------------------- { - html: "Sort by", + html: i18n('sort_by'), items: [ { - html: `Name`, + html: i18n('name'), icon: $(el_desktop).attr('data-sort_by') === 'name' ? '✓' : '', onClick: async function(){ sort_items(el_desktop, 'name', $(el_desktop).attr('data-sort_order')); @@ -633,7 +633,7 @@ async function UIDesktop(options){ } }, { - html: `Date modified`, + html: i18n('date_modified'), icon: $(el_desktop).attr('data-sort_by') === 'modified' ? '✓' : '', onClick: async function(){ sort_items(el_desktop, 'modified', $(el_desktop).attr('data-sort_order')); @@ -641,7 +641,7 @@ async function UIDesktop(options){ } }, { - html: `Type`, + html: i18n('type'), icon: $(el_desktop).attr('data-sort_by') === 'type' ? '✓' : '', onClick: async function(){ sort_items(el_desktop, 'type', $(el_desktop).attr('data-sort_order')); @@ -649,7 +649,7 @@ async function UIDesktop(options){ } }, { - html: `Size`, + html: i18n('size'), icon: $(el_desktop).attr('data-sort_by') === 'size' ? '✓' : '', onClick: async function(){ sort_items(el_desktop, 'size', $(el_desktop).attr('data-sort_order')); @@ -661,7 +661,7 @@ async function UIDesktop(options){ // ------------------------------------------- '-', { - html: `Ascending`, + html: i18n('ascending'), icon: $(el_desktop).attr('data-sort_order') === 'asc' ? '✓' : '', onClick: async function(){ const sort_by = $(el_desktop).attr('data-sort_by') @@ -670,7 +670,7 @@ async function UIDesktop(options){ } }, { - html: `Descending`, + html: i18n('descending'), icon: $(el_desktop).attr('data-sort_order') === 'desc' ? '✓' : '', onClick: async function(){ const sort_by = $(el_desktop).attr('data-sort_by') @@ -684,7 +684,7 @@ async function UIDesktop(options){ // Refresh // ------------------------------------------- { - html: "Refresh", + html: i18n('refresh'), onClick: function(){ refresh_item_container(el_desktop); } @@ -693,7 +693,8 @@ async function UIDesktop(options){ // Show/Hide hidden files // ------------------------------------------- { - html: `${window.user_preferences.show_hidden_files ? 'Hide' : 'Show'} hidden files`, + html: i18n('show_hidden'), + icon: window.user_preferences.show_hidden_files ? '✓' : '', onClick: function(){ window.mutate_user_preferences({ show_hidden_files : !window.user_preferences.show_hidden_files, @@ -717,7 +718,7 @@ async function UIDesktop(options){ // Paste // ------------------------------------------- { - html: "Paste", + html: i18n('paste'), disabled: clipboard.length > 0 ? false : true, onClick: function(){ if(clipboard_op === 'copy') @@ -730,7 +731,7 @@ async function UIDesktop(options){ // Undo // ------------------------------------------- { - html: "Undo", + html: i18n('undo'), disabled: actions_history.length > 0 ? false : true, onClick: function(){ undo_last_action(); @@ -740,21 +741,12 @@ async function UIDesktop(options){ // Upload Here // ------------------------------------------- { - html: "Upload Here", + html: i18n('upload_here'), onClick: function(){ init_upload_using_dialog(el_desktop); } }, // ------------------------------------------- - // Request Files - // ------------------------------------------- - // { - // html: "Request Files", - // onClick: function(){ - // UIWindowRequestFiles({dir_path: desktop_path}) - // } - // }, - // ------------------------------------------- // - // ------------------------------------------- '-', @@ -762,7 +754,7 @@ async function UIDesktop(options){ // Change Desktop Background… // ------------------------------------------- { - html: "Change Desktop Background…", + html: i18n('change_desktop_background'), onClick: function(){ UIWindowDesktopBGSettings(); } @@ -1136,7 +1128,7 @@ $(document).on('click', '.user-options-menu-btn', async function(e){ // My Websites //-------------------------------------------------- { - html: "My Websites", + html: i18n('my_websites'), onClick: async function(){ UIWindowMyWebsites(); } @@ -1145,7 +1137,7 @@ $(document).on('click', '.user-options-menu-btn', async function(e){ // Change Username //-------------------------------------------------- { - html: "Change Username", + html: i18n('change_username'), onClick: async function(){ UIWindowChangeUsername(); } @@ -1155,7 +1147,7 @@ $(document).on('click', '.user-options-menu-btn', async function(e){ // Change Password //-------------------------------------------------- { - html: "Change Password", + html: i18n('change_password'), onClick: async function(){ UIWindowChangePassword(); } @@ -1164,7 +1156,7 @@ $(document).on('click', '.user-options-menu-btn', async function(e){ // Contact Us //-------------------------------------------------- { - html: "Contact Us", + html: i18n('contact_us'), onClick: async function(){ UIWindowFeedback(); } @@ -1178,7 +1170,7 @@ $(document).on('click', '.user-options-menu-btn', async function(e){ // Log Out //-------------------------------------------------- { - html: "Log Out", + html: i18n('log_out'), onClick: async function(){ // see if there are any open windows, if yes notify user if($('.window-app').length > 0){ diff --git a/src/UI/UIItem.js b/src/UI/UIItem.js index e90f420f..183fbd5b 100644 --- a/src/UI/UIItem.js +++ b/src/UI/UIItem.js @@ -736,7 +736,7 @@ function UIItem(options){ // ------------------------------------------- if(are_trashed){ menu_items.push({ - html: "Restore", + html: i18n('restore'), onClick: function(){ $selected_items.each(function() { const ell = this; @@ -755,7 +755,7 @@ function UIItem(options){ // Donwload // ------------------------------------------- menu_items.push({ - html: 'Download', + html: i18n('Download'), onClick: async function(){ let items = []; for (let index = 0; index < $selected_items.length; index++) { @@ -769,7 +769,7 @@ function UIItem(options){ // Zip // ------------------------------------------- menu_items.push({ - html: 'Zip', + html: i18n('zip'), onClick: async function(){ let items = []; for (let index = 0; index < $selected_items.length; index++) { @@ -788,7 +788,7 @@ function UIItem(options){ // Cut // ------------------------------------------- menu_items.push({ - html: "Cut", + html: i18n('cut'), onClick: function(){ window.clipboard_op= 'move'; window.clipboard = []; @@ -804,7 +804,7 @@ function UIItem(options){ // ------------------------------------------- if(!are_trashed){ menu_items.push({ - html: "Copy", + html: i18n('copy'), onClick: function(){ window.clipboard_op= 'copy'; window.clipboard = []; @@ -824,7 +824,7 @@ function UIItem(options){ // ------------------------------------------- if(are_trashed){ menu_items.push({ - html: 'Delete Permanently', + html: i18n('delete_permanently'), onClick: async function(){ const alert_resp = await UIAlert({ message: `Are you sure you want to permanently delete these items?`, @@ -863,7 +863,7 @@ function UIItem(options){ // ------------------------------------------- if(!are_trashed && window.feature_flags.create_shortcut){ menu_items.push({ - html: 'Create Shortcut', + html: i18n('create_shortcut'), onClick: async function(){ $selected_items.each(function() { let base_dir = path.dirname($(this).attr('data-path')); @@ -889,7 +889,7 @@ function UIItem(options){ // ------------------------------------------- if(!are_trashed){ menu_items.push({ - html: 'Delete', + html: i18n('delete'), onClick: async function(){ move_items($selected_items, trash_path); } @@ -909,7 +909,7 @@ function UIItem(options){ // ------------------------------------------- if(!is_trashed){ menu_items.push({ - html: 'Open', + html: i18n('open'), onClick: function(){ open_item({item: el_item}); } @@ -965,7 +965,7 @@ function UIItem(options){ } // add all suitable apps menu_items.push({ - html: 'Open With', + html: i18n('open_with'), items: items, }); @@ -981,7 +981,7 @@ function UIItem(options){ // ------------------------------------------- if($(el_item).closest('.window-body').length > 0 && options.is_dir){ menu_items.push({ - html: 'Open in New Window', + html: i18n('open_in_new_window'), onClick: function(){ if(options.is_dir){ open_item({item: el_item, new_window: true}) @@ -1000,7 +1000,7 @@ function UIItem(options){ // ------------------------------------------- if(!is_trashed && !is_trash && options.is_dir){ menu_items.push({ - html: 'Publish As Website', + html: i18n('publish_as_website'), disabled: !options.is_dir, onClick: async function () { if(window.require_email_verification_to_publish_website){ @@ -1027,7 +1027,7 @@ function UIItem(options){ // ------------------------------------------- if(!is_trashed && !is_trash && options.is_dir){ menu_items.push({ - html: 'Deploy As App', + html: i18n('deploy_as_app'), disabled: !options.is_dir, onClick: async function () { launch_app({ @@ -1049,19 +1049,18 @@ function UIItem(options){ // ------------------------------------------- if(is_trash){ menu_items.push({ - html: 'Empty Trash', + html: i18n('empty_trash'), onClick: async function(){ empty_trash(); } }); - } // ------------------------------------------- // Donwload // ------------------------------------------- if(!is_trash && !is_trashed && (options.associated_app_name === null || options.associated_app_name === undefined)){ menu_items.push({ - html: 'Download', + html: i18n('Download'), disabled: options.is_dir && !window.feature_flags.download_directory, onClick: async function(){ if(options.is_dir) @@ -1078,11 +1077,11 @@ function UIItem(options){ // ------------------------------------------- if(!is_trashed && !is_trash && (options.associated_app_name === null || options.associated_app_name === undefined)){ menu_items.push({ - html: 'Get Copy Link', + html: i18n('get_copy_link'), onClick: async function(){ if(window.user.is_temp && !await UIWindowSaveAccount({ - message: 'Please create an account to proceed.', + message: i18n('save_account_to_get_copy_link'), send_confirmation_code: true, window_options: { backdrop: true, @@ -1107,7 +1106,7 @@ function UIItem(options){ // ------------------------------------------- if(!is_trash && !is_trashed && !$(el_item).attr('data-path').endsWith('.zip')){ menu_items.push({ - html: "Zip", + html: i18n('zip'), onClick: function(){ zipItems(el_item, path.dirname($(el_item).attr('data-path')), false); } @@ -1118,7 +1117,7 @@ function UIItem(options){ // ------------------------------------------- if(!is_trash && !is_trashed && $(el_item).attr('data-path').endsWith('.zip')){ menu_items.push({ - html: "Unzip", + html: i18n('unzip'), onClick: async function(){ const zip = new JSZip(); let filPath = $(el_item).attr('data-path'); @@ -1146,7 +1145,7 @@ function UIItem(options){ // ------------------------------------------- if(is_trashed){ menu_items.push({ - html: 'Restore', + html: i18n('restore'), onClick: async function(){ let metadata = $(el_item).attr('data-metadata') === '' ? {} : JSON.parse($(el_item).attr('data-metadata')) move_items([el_item], path.dirname(metadata.original_path)); @@ -1163,7 +1162,7 @@ function UIItem(options){ // ------------------------------------------- if($(el_item).attr('data-immutable') === '0'){ menu_items.push({ - html: "Cut", + html: i18n('cut'), onClick: function(){ window.clipboard_op= 'move'; window.clipboard= [options.path]; @@ -1175,7 +1174,7 @@ function UIItem(options){ // ------------------------------------------- if(!is_trashed && !is_trash){ menu_items.push({ - html: "Copy", + html: i18n('copy'), onClick: function(){ window.clipboard_op= 'copy'; window.clipboard= [{path: options.path}]; @@ -1187,7 +1186,7 @@ function UIItem(options){ // ------------------------------------------- if($(el_item).attr('data-is_dir') === '1' && !is_trashed && !is_trash){ menu_items.push({ - html: "Paste Into Folder", + html: i18n('paste_into_folder'), disabled: clipboard.length > 0 ? false : true, onClick: function(){ if(clipboard_op === 'copy') @@ -1208,7 +1207,7 @@ function UIItem(options){ // ------------------------------------------- if(!is_trashed && window.feature_flags.create_shortcut){ menu_items.push({ - html: 'Create Shortcut', + html: i18n('create_shortcut'), onClick: async function(){ let base_dir = path.dirname($(el_item).attr('data-path')); // Trash on Desktop is a special case @@ -1232,7 +1231,7 @@ function UIItem(options){ // ------------------------------------------- if($(el_item).attr('data-immutable') === '0' && !is_trashed){ menu_items.push({ - html: 'Delete', + html: i18n('delete'), onClick: async function(){ move_items([el_item], trash_path); } @@ -1243,7 +1242,7 @@ function UIItem(options){ // ------------------------------------------- if(is_trashed){ menu_items.push({ - html: 'Delete Permanently', + html: i18n('delete_permanently'), onClick: async function(){ const alert_resp = await UIAlert({ message: `Are you sure you want to permanently delete this item?`, @@ -1280,7 +1279,7 @@ function UIItem(options){ // ------------------------------------------- if($(el_item).attr('data-immutable') === '0' && !is_trashed && !is_trash){ menu_items.push({ - html: "Rename", + html: i18n('rename'), onClick: function(){ activate_item_name_editor(el_item) } @@ -1294,7 +1293,7 @@ function UIItem(options){ // Properties // ------------------------------------------- menu_items.push({ - html: "Properties", + html: i18n('properties'), onClick: function(){ let window_height = 500; let window_width = 450; @@ -1387,8 +1386,8 @@ $(document).on('contextmenu', '.item-has-website-url-badge', async function(e){ items: [ // Open { - html: `Open in New Tab ` , - html_active: `Open in New Tab ` , + html: `${i18n('open_in_new_tab')} ` , + html_active: `${i18n('open_in_new_tab')} ` , onClick: function(){ const website_url = $(e.target).closest('.item').attr('data-website_url'); if(website_url){ @@ -1398,7 +1397,7 @@ $(document).on('contextmenu', '.item-has-website-url-badge', async function(e){ }, // Copy Link { - html: 'Copy Link', + html: i18n('copy_link'), onClick: async function(){ const website_url = $(e.target).closest('.item').attr('data-website_url'); if(website_url){ @@ -1499,7 +1498,7 @@ window.activate_item_name_editor= function(el_item){ } // files in trash cannot be renamed, user should be notified with an Alert. else if(path.dirname($(el_item).attr('data-path')) === window.trash_path){ - UIAlert(`This item can't be renamed because it's in the trash. To rename this item, first drag it out of the Trash.`) + UIAlert(i18n('items_in_trash_cannot_be_renamed')); return; } diff --git a/src/UI/UIPrompt.js b/src/UI/UIPrompt.js index c517b427..333234ae 100644 --- a/src/UI/UIPrompt.js +++ b/src/UI/UIPrompt.js @@ -37,8 +37,8 @@ function UIPrompt(options){ // provide an 'OK' button if no buttons are provided if(!options.buttons || options.buttons.length === 0){ options.buttons = [ - {label: 'Cancel', value: false, type: 'default'}, - {label: 'OK', value: true, type: 'primary'}, + {label: i18n('Cancel'), value: false, type: 'default'}, + {label: i18n('OK'), value: true, type: 'primary'}, ] } @@ -52,8 +52,8 @@ function UIPrompt(options){ // buttons if(options.buttons && options.buttons.length > 0){ h += `
`; - h += ``; - h += ``; + h += ``; + h += ``; h += `
`; } diff --git a/src/UI/UITaskbar.js b/src/UI/UITaskbar.js index 0ab89bb8..9c2a5ac6 100644 --- a/src/UI/UITaskbar.js +++ b/src/UI/UITaskbar.js @@ -50,7 +50,7 @@ async function UITaskbar(options){ //--------------------------------------------- UITaskbarItem({ icon: window.icons['start.svg'], - name: 'Start', + name: i18n('start'), sortable: false, keep_in_taskbar: true, disable_context_menu: true, @@ -95,7 +95,7 @@ async function UITaskbar(options){ // ------------------------------------------- if(launch_apps.recent.length > 0){ // heading - apps_str += `

Recent

`; + apps_str += `

${i18n('recent')}

`; // apps apps_str += `
`; @@ -116,7 +116,7 @@ async function UITaskbar(options){ if(launch_apps.recommended.length > 0){ // heading apps_str += `

Recommended

`; - + // apps apps_str += ``; const el_window = await UIWindow({ @@ -93,7 +93,7 @@ async function UIWindowChangePassword(){ return; } else if(new_password !== confirm_new_password){ - $(el_window).find('.form-error-msg').html('`New Password` and `Confirm New Password` do not match.'); + $(el_window).find('.form-error-msg').html(i18n('passwords_do_not_match')); $(el_window).find('.form-error-msg').fadeIn(); return; } @@ -113,7 +113,7 @@ async function UIWindowChangePassword(){ new_pass: new_password, }), success: function (data){ - $(el_window).find('.form-success-msg').html('Password changed successfully.'); + $(el_window).find('.form-success-msg').html(i18n('password_changed')); $(el_window).find('.form-success-msg').fadeIn(); $(el_window).find('input').val(''); }, diff --git a/src/UI/UIWindowChangeUsername.js b/src/UI/UIWindowChangeUsername.js index 817bfef8..4fa2bb7e 100644 --- a/src/UI/UIWindowChangeUsername.js +++ b/src/UI/UIWindowChangeUsername.js @@ -30,16 +30,16 @@ async function UIWindowChangeUsername(){ h += `
`; // new username h += `
`; - h += ``; + h += ``; h += ``; h += `
`; // Change Username - h += ``; + h += ``; h += `
`; const el_window = await UIWindow({ - title: 'Change Username', + title: i18n('change_username'), app: 'change-username', single_instance: true, icon: null, @@ -78,7 +78,7 @@ async function UIWindowChangeUsername(){ const new_username = $(el_window).find('.new-username').val(); if(!new_username){ - $(el_window).find('.form-error-msg').html('All fields are required.'); + $(el_window).find('.form-error-msg').html(i18n('all_fields_required')); $(el_window).find('.form-error-msg').fadeIn(); return; } @@ -102,7 +102,7 @@ async function UIWindowChangeUsername(){ new_username: new_username, }), success: function (data){ - $(el_window).find('.form-success-msg').html('Username updated successfully.'); + $(el_window).find('.form-success-msg').html(i18n('username_changed')); $(el_window).find('.form-success-msg').fadeIn(); $(el_window).find('input').val(''); // update auth data diff --git a/src/UI/UIWindowClaimReferral.js b/src/UI/UIWindowClaimReferral.js index d7715f7c..68f558e1 100644 --- a/src/UI/UIWindowClaimReferral.js +++ b/src/UI/UIWindowClaimReferral.js @@ -26,9 +26,9 @@ async function UIWindowClaimReferral(options){ h += `
`; h += `
×
`; h += ``; - h += `

You have been referred to Puter by a friend!

`; - h += `

Create an account and confirm your email address to receive 1 GB of free storage. Your friend will get 1 GB of free storage too.

`; - h += ``; + h += `

${i18n('you_have_been_referred_to_puter_by_a_friend')}

`; + h += `

${i18n('confirm_account_for_free_referral_storage_c2a')}

`; + h += ``; h += `
`; const el_window = await UIWindow({ diff --git a/src/UI/UIWindowColorPicker.js b/src/UI/UIWindowColorPicker.js index a8d35121..400adbb3 100644 --- a/src/UI/UIWindowColorPicker.js +++ b/src/UI/UIWindowColorPicker.js @@ -42,13 +42,13 @@ async function UIWindowColorPicker(options){ h += ``; // Select button - h += `` + h += `` h += ``; h += ``; h += ``; const el_window = await UIWindow({ - title: 'Select color…', + title: i18n('select_color'), app: 'color-picker', single_instance: true, icon: null, diff --git a/src/UI/UIWindowConfirmDownload.js b/src/UI/UIWindowConfirmDownload.js index b3814260..b9605ad2 100644 --- a/src/UI/UIWindowConfirmDownload.js +++ b/src/UI/UIWindowConfirmDownload.js @@ -34,17 +34,17 @@ async function UIWindowConfirmDownload(options){ // Item information h += `
`; // Name - h += `

Name: ${options.name ?? options.url}

`; + h += `

${i18n('name')}: ${options.name ?? options.url}

`; // Type - h += `

Type: ${options.is_dir === '1' || options.is_dir === 'true' ? 'Folder' : options.type ?? 'Unknown File Type'}

`; + h += `

${i18n('type')}: ${options.is_dir === '1' || options.is_dir === 'true' ? 'Folder' : options.type ?? 'Unknown File Type'}

`; // Source - h += `

From: ${options.source}

`; + h += `

${i18n('from')}: ${options.source}

`; h += `
`; h += ``; // Download - h += ``; + h += ``; // Cancel - h += ``; + h += ``; h +=``; const el_window = await UIWindow({ diff --git a/src/UI/UIWindowCopyProgress.js b/src/UI/UIWindowCopyProgress.js index 738da14b..d40bda97 100644 --- a/src/UI/UIWindowCopyProgress.js +++ b/src/UI/UIWindowCopyProgress.js @@ -29,7 +29,7 @@ async function UIWindowCopyProgress(options){ // Progress report h +=`
`; // msg - h += `Copying `; + h += `${i18n('copying')} `; h += ``; h += `
`; // progress @@ -42,7 +42,7 @@ async function UIWindowCopyProgress(options){ h += ``; const el_window = await UIWindow({ - title: `Copying`, + title: i18n('copying'), icon: window.icons[`app-icon-copying.svg`], uid: null, is_dir: false, diff --git a/src/UI/UIWindowDesktopBGSettings.js b/src/UI/UIWindowDesktopBGSettings.js index 37c38318..3b0c9838 100644 --- a/src/UI/UIWindowDesktopBGSettings.js +++ b/src/UI/UIWindowDesktopBGSettings.js @@ -30,28 +30,28 @@ async function UIWindowDesktopBGSettings(){ h += `
`; // type - h += ``; + h += ``; h += ``; // Picture h += `
`; - h += ``; - h += ``; - h += ``; + h += ``; + h += ``; + h += ``; h += ``; h += `
` // Color h += `
`; - h += ``; + h += ``; h += `
`; h += `
`; h += `
`; @@ -69,14 +69,14 @@ async function UIWindowDesktopBGSettings(){ h += `
`; h += `
` - h += ``; - h += ``; + h += ``; + h += ``; h += `
`; h += `
`; const el_window = await UIWindow({ - title: 'Change Desktop Background…', + title: i18n('change_desktop_background'), icon: null, uid: null, is_dir: false, diff --git a/src/UI/UIWindowDownloadDirProg.js b/src/UI/UIWindowDownloadDirProg.js index c90f1e69..8a9ba5c9 100644 --- a/src/UI/UIWindowDownloadDirProg.js +++ b/src/UI/UIWindowDownloadDirProg.js @@ -25,7 +25,7 @@ async function UIWindowDownloadDirProg(options){ let h = ''; // Loading spinner h +=`circle anim`; - h += `

${options.defaultText ?? 'Preparing...'}

`; + h += `

${options.defaultText ?? i18n('preparing')}

`; const el_window = await UIWindow({ title: 'Instant Login!', diff --git a/src/UI/UIWindowDownloadProgress.js b/src/UI/UIWindowDownloadProgress.js index 8bfd1cf0..5503a5bf 100644 --- a/src/UI/UIWindowDownloadProgress.js +++ b/src/UI/UIWindowDownloadProgress.js @@ -29,7 +29,7 @@ async function UIWindowDownloadProgress(options){ // Progress report h +=`
`; // msg - h += `Downloading ${options.item_name ?? ''}`; + h += `${i18n('downloading')} ${options.item_name ?? ''}`; h += `
`; // Progress h += `
`; diff --git a/src/UI/UIWindowEmailConfirmationRequired.js b/src/UI/UIWindowEmailConfirmationRequired.js index 14b7aaf5..88eb9ca7 100644 --- a/src/UI/UIWindowEmailConfirmationRequired.js +++ b/src/UI/UIWindowEmailConfirmationRequired.js @@ -47,10 +47,10 @@ function UIWindowEmailConfirmationRequired(options){ h += ``; h += ``; h += `
`; - h += `Re-send Confirmation Code`; + h += `${i18n('resend_confirmation_code')}`; if(options.logout_in_footer){ h += ` • `; - h += `Log Out`; + h += `${i18n('log_out')}`; } h += `
`; h += `
`; diff --git a/src/UI/UIWindowFeedback.js b/src/UI/UIWindowFeedback.js index aaba86ce..5e0b18f7 100644 --- a/src/UI/UIWindowFeedback.js +++ b/src/UI/UIWindowFeedback.js @@ -28,18 +28,18 @@ async function UIWindowQR(options){ // success h += `
`; h += ``; - h += `

Thank you for contacting us. If you have an email associated with your account, you will hear back from us as soon as possible.

`; + h += `

${i18n('feedback_sent_confirmation')}

`; h+= `
`; // form h += `
`; - h += `

Please use the form below to send us your feedback, comments, and bug reports.

`; + h += `

${i18n('feedback_c2a')}

`; h += ``; - h += ``; + h += ``; h += `
`; h += `
`; const el_window = await UIWindow({ - title: 'Contact Us', + title: i18n('contact_us'), app: 'feedback', single_instance: true, icon: null, diff --git a/src/UI/UIWindowFontPicker.js b/src/UI/UIWindowFontPicker.js index 5e1b23b8..f4208b14 100644 --- a/src/UI/UIWindowFontPicker.js +++ b/src/UI/UIWindowFontPicker.js @@ -60,7 +60,7 @@ async function UIWindowFontPicker(options){ h += ``; // Select - h += `` + h += `` h += ``; h += ``; h += ``; diff --git a/src/UI/UIWindowGetCopyLink.js b/src/UI/UIWindowGetCopyLink.js index 8f81790e..769383f2 100644 --- a/src/UI/UIWindowGetCopyLink.js +++ b/src/UI/UIWindowGetCopyLink.js @@ -69,7 +69,11 @@ async function UIWindowGetCopyLink(options){ $(el_window).find('.window-body .downloadable-link').val(url); $(el_window).find('.window-body .share-copy-link-on-social').on('click', function(e){ - const social_links = socialLink({url: url, title: `Get a copy of '${options.name}' on Puter.com!`, description: `Get a copy of '${options.name}' on Puter.com!`}); + const social_links = socialLink({ + url: url, + title: i18n('get_a_copy_of_on_puter', options.name, false), + description: i18n('get_a_copy_of_on_puter', options.name, false), + }); let social_links_html = ``; social_links_html += `
`; diff --git a/src/UI/UIWindowItemProperties.js b/src/UI/UIWindowItemProperties.js index db9aaafe..821483b1 100644 --- a/src/UI/UIWindowItemProperties.js +++ b/src/UI/UIWindowItemProperties.js @@ -25,8 +25,8 @@ async function UIWindowItemProperties(item_name, item_path, item_uid, left, top, h += `
`; // tabs h += `
`; - h += `
General
`; - h += `
Versions
`; + h += `
${i18n('general')}
`; + h += `
${i18n('versions')}
`; h += `
`; h+= `
`; @@ -44,7 +44,7 @@ async function UIWindowItemProperties(item_name, item_path, item_uid, left, top, h += `Versions`; h += `Associated Websites`; h += ``; - h += `Access Granted To`; + h += `${i18n('access_granted_to')}`; h += ``; h += `
`; diff --git a/src/UI/UIWindowLogin.js b/src/UI/UIWindowLogin.js index c7937884..145a1f84 100644 --- a/src/UI/UIWindowLogin.js +++ b/src/UI/UIWindowLogin.js @@ -43,12 +43,12 @@ async function UIWindowLogin(options){ h += ``; // username/email h += `
`; - h += ``; + h += ``; h += ``; h += `
`; // password with conditional type based based on options.show_password h += `
`; - h += ``; + h += ``; h += ``; // show/hide icon h += ` @@ -56,15 +56,15 @@ async function UIWindowLogin(options){ `; h += `
`; // login - h += ``; + h += ``; // password recovery - h += `

Forgot password?

`; + h += `

${i18n('forgot_pass_c2a')}

`; h += ``; h += `
`; // create account link if(options.show_signup_button === undefined || options.show_signup_button){ h += `
`; - h += ``; + h += ``; h += `
`; } h += `
`; diff --git a/src/UI/UIWindowMoveProgress.js b/src/UI/UIWindowMoveProgress.js index 18cb7f9d..2b492b33 100644 --- a/src/UI/UIWindowMoveProgress.js +++ b/src/UI/UIWindowMoveProgress.js @@ -29,7 +29,7 @@ async function UIWindowMoveProgress(options){ // Progress report h +=`
`; // msg - h += `Moving `; + h += `${i18n('moving')} `; h += ``; h += `
`; // progress diff --git a/src/UI/UIWindowMyWebsites.js b/src/UI/UIWindowMyWebsites.js index e1a6c076..54397920 100644 --- a/src/UI/UIWindowMyWebsites.js +++ b/src/UI/UIWindowMyWebsites.js @@ -90,10 +90,10 @@ async function UIWindowMyWebsites(options){ h += `

`; h += `

`; h += ``; - h += `Disassociate Folder`; + h += `${i18n('disassociate_dir')}`; h += `

`; } - h += `

No directory associated with this address.

`; + h += `

${i18n('no_dir_associated_with_site')}

`; h += ``; } $(el_window).find('.window-body').html(h); @@ -105,7 +105,7 @@ async function UIWindowMyWebsites(options){ margin-bottom: 50px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - color: #596c7c;">You haven't published any websites!

`); + color: #596c7c;">${i18n('no_websites_published')}

`); } }, Date.now() - init_ts < 1000 ? 0 : 2000); }) @@ -136,10 +136,11 @@ $(document).on('click', '.mywebsites-site-setting', function(e){ html: `Release Address`, onClick: async function(){ const alert_resp = await UIAlert({ - message: `Are you sure you want to release this address?`, + message: i18n('release_address_confirmation'), buttons:[ { - label: 'Yes, Release It', + label: i18n('yes_release_it'), + value: 'yes', type: 'primary', }, { @@ -147,7 +148,7 @@ $(document).on('click', '.mywebsites-site-setting', function(e){ }, ] }) - if(alert_resp !== 'Yes, Release It'){ + if(alert_resp !== 'yes'){ return; } diff --git a/src/UI/UIWindowNewFolderProgress.js b/src/UI/UIWindowNewFolderProgress.js index 3f01e8af..0f04d7db 100644 --- a/src/UI/UIWindowNewFolderProgress.js +++ b/src/UI/UIWindowNewFolderProgress.js @@ -29,7 +29,7 @@ async function UIWindowNewFolderProgress(options){ // message h +=`
`; // text - h += `Taking a little longer than usual. Please wait...`; + h += `${i18n('taking_longer_than_usual')}`; h += `
`; h +=``; h += ``; diff --git a/src/UI/UIWindowNewPassword.js b/src/UI/UIWindowNewPassword.js index 15dc3b0a..204c0771 100644 --- a/src/UI/UIWindowNewPassword.js +++ b/src/UI/UIWindowNewPassword.js @@ -34,17 +34,17 @@ async function UIWindowNewPassword(options){ h += `
`; // new password h += `
`; - h += ``; + h += ``; h += ``; h += `
`; // confirm new password h += `
`; - h += ``; + h += ``; h += ``; h += `
`; // Change Password - h += ``; + h += ``; h += ``; const el_window = await UIWindow({ diff --git a/src/UI/UIWindowProgressEmptyTrash.js b/src/UI/UIWindowProgressEmptyTrash.js index e771fe78..b8efabd7 100644 --- a/src/UI/UIWindowProgressEmptyTrash.js +++ b/src/UI/UIWindowProgressEmptyTrash.js @@ -29,13 +29,13 @@ async function UIWindowProgressEmptyTrash(options){ // message h +=`
`; // text - h += `Emptying the Trash...`; + h += `${i18n('emptying_trash')}`; h += `
`; h +=``; h += ``; const el_window = await UIWindow({ - title: `Creating New Folder`, + title: i18n('emptying_trash'), icon: window.icons[`app-icon-newfolder.svg`], uid: null, is_dir: false, diff --git a/src/UI/UIWindowPublishWebsite.js b/src/UI/UIWindowPublishWebsite.js index f5a0ffa4..a0dbb9cc 100644 --- a/src/UI/UIWindowPublishWebsite.js +++ b/src/UI/UIWindowPublishWebsite.js @@ -26,7 +26,7 @@ async function UIWindowPublishWebsite(target_dir_uid, target_dir_name, target_di // success h += `
`; h += ``; - h += `

${target_dir_name} has been published to:

`; + h += `

${i18n('dir_published_as_website', `${target_dir_name}`)}

`; h += `

`; h += ``; h+= `
`; @@ -36,13 +36,13 @@ async function UIWindowPublishWebsite(target_dir_uid, target_dir_name, target_di h += `
`; // subdomain h += `
`; - h += ``; + h += ``; h += `
https://.${window.hosting_domain}
`; h += `
`; // uid h += ``; // Publish - h += `` + h += `` h += ``; h += ``; diff --git a/src/UI/UIWindowQR.js b/src/UI/UIWindowQR.js index b66136f7..b69c7a9e 100644 --- a/src/UI/UIWindowQR.js +++ b/src/UI/UIWindowQR.js @@ -27,7 +27,7 @@ async function UIWindowQR(options){ // close button containing the multiplication sign h += `
×
`; h += `
`; - h += `

Scan the code below to log into this session from other devices

`; + h += `

${i18n('scan_qr_c2a')}

`; h += `
`; const el_window = await UIWindow({ diff --git a/src/UI/UIWindowRecoverPassword.js b/src/UI/UIWindowRecoverPassword.js index 8e37acef..fd6591f5 100644 --- a/src/UI/UIWindowRecoverPassword.js +++ b/src/UI/UIWindowRecoverPassword.js @@ -26,13 +26,13 @@ function UIWindowRecoverPassword(options){ let h = ''; h += `
`; - h += `

Recover Password

`; + h += `

${i18n('recover_password')}

`; h += `
`; h += `

`; h += `
`; - h += ``; + h += ``; h += ``; - h += ``; + h += ``; h += `
`; h += `
`; diff --git a/src/UI/UIWindowRefer.js b/src/UI/UIWindowRefer.js index b2fa78bd..aba0bc0e 100644 --- a/src/UI/UIWindowRefer.js +++ b/src/UI/UIWindowRefer.js @@ -29,8 +29,8 @@ async function UIWindowRefer(options){ h += `
`; h += `
×
`; h += ``; - h += `

Get 1 GB for every friend who creates and confirms an account on Puter. Your friend will get 1 GB too!

`; - h += ``; + h += `

${i18n('refer_friends_c2a')}

`; + h += ``; h += ``; h += `` h += ``; @@ -72,11 +72,11 @@ async function UIWindowRefer(options){ $(el_window).find('.window-body .downloadable-link').val(url); $(el_window).find('.window-body .share-copy-link-on-social').on('click', function(e){ - const social_links = socialLink({url: url, title: `Get 1 GB of free storage on Puter.com!`, description: `Get 1 GB of free storage on Puter.com!`}); + const social_links = socialLink({url: url, title: i18n('refer_friends_social_media_c2a'), description: i18n('refer_friends_social_media_c2a')}); let social_links_html = ``; social_links_html += `
`; - social_links_html += `

Share to

` + social_links_html += `

${i18n('share_to')}

` social_links_html += `` social_links_html += `` social_links_html += `` diff --git a/src/UI/UIWindowSaveAccount.js b/src/UI/UIWindowSaveAccount.js index 2c5a367c..3a57ba9d 100644 --- a/src/UI/UIWindowSaveAccount.js +++ b/src/UI/UIWindowSaveAccount.js @@ -32,39 +32,39 @@ async function UIWindowSaveAccount(options){ // success h += ``; // form h += ``; h += `
`; diff --git a/src/UI/UIWindowSessionList.js b/src/UI/UIWindowSessionList.js index 640567fc..fb128452 100644 --- a/src/UI/UIWindowSessionList.js +++ b/src/UI/UIWindowSessionList.js @@ -28,16 +28,16 @@ async function UIWindowSessionList(options){ return new Promise(async (resolve) => { let h = ''; h += `
`; - h += `
Signing in...
` + h += `
${i18n('signing_in')}
` h += `
`; - h += `

Sign in with Puter

` + h += `

${i18n('sign_in_with_puter')}

` for (let index = 0; index < logged_in_users.length; index++) { const l_user = logged_in_users[index]; h += `
${l_user.username}
`; } h += `
`; - h += `
`; + h += `
`; h += `
`; const el_window = await UIWindow({ diff --git a/src/UI/UIWindowSignup.js b/src/UI/UIWindowSignup.js index 5c0e25c4..fce5df86 100644 --- a/src/UI/UIWindowSignup.js +++ b/src/UI/UIWindowSignup.js @@ -40,39 +40,39 @@ function UIWindowSignup(options){ // Form h += `
`; // title - h += `

Create Free Account

`; + h += `

${i18n('create_free_account')}

`; // signup form h += ``; h += `
`; // login link // create account link h += `
`; - h += ``; + h += ``; h += `
`; h += `
`; diff --git a/src/UI/UIWindowUploadProgress.js b/src/UI/UIWindowUploadProgress.js index 1612c93b..e436fc74 100644 --- a/src/UI/UIWindowUploadProgress.js +++ b/src/UI/UIWindowUploadProgress.js @@ -29,19 +29,19 @@ async function UIWindowUploadProgress(options){ // Progress report h +=`
`; // msg - h += `Preparing for upload...`; + h += `${i18n('preparing_for_upload')}`; h += `
`; // progress h += `
`; h += `
`; h += `
`; // cancel - h += ``; + h += ``; h +=``; h += ``; const el_window = await UIWindow({ - title: `Upload`, + title: i18n('Upload'), icon: window.icons[`app-icon-uploader.svg`], uid: null, is_dir: false, diff --git a/src/helpers.js b/src/helpers.js index 7b0b795e..03128b9e 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -409,17 +409,17 @@ window.globToRegExp = function (glob, opts) { */ window.validate_fsentry_name = function(name){ if(!name) - throw {message: 'Name cannot be empty.'} + throw {message: i18n('name_cannot_be_empty')} else if(!isString(name)) - throw {message: "Name can only be a string."} + throw {message: i18n('name_must_be_string')} else if(name.includes('/')) - throw {message: "Name cannot contain the '/' character."} + throw {message: i18n('name_cannot_contain_slash')} else if(name === '.') - throw {message: "Name can not be the '.' character."}; + throw {message: i18n('name_cannot_contain_period')}; else if(name === '..') - throw {message: "Name can not be the '..' character."}; + throw {message: i18n('name_cannot_contain_double_period')}; else if(name.length > window.max_item_name_length) - throw {message: `Name can not be longer than ${config.max_item_name_length} characters`} + throw {message: i18n('name_too_long', config.max_item_name_length)} else return true } diff --git a/src/helpers/new_context_menu_item.js b/src/helpers/new_context_menu_item.js index 28f22298..05a7eeaf 100644 --- a/src/helpers/new_context_menu_item.js +++ b/src/helpers/new_context_menu_item.js @@ -28,11 +28,11 @@ const new_context_menu_item = function(dirname, append_to_element){ return { - html: "New", + html: i18n('new'), items: [ // New Folder { - html: "New Folder", + html: i18n('new_folder'), icon: ``, onClick: function(){ create_folder(dirname, append_to_element); @@ -42,7 +42,7 @@ const new_context_menu_item = function(dirname, append_to_element){ '-', // Text Document { - html: `Text Document`, + html: i18n('text_document'), icon: ``, onClick: async function(){ create_file({dirname: dirname, append_to_element: append_to_element, name: 'New File.txt'}); @@ -50,7 +50,7 @@ const new_context_menu_item = function(dirname, append_to_element){ }, // HTML Document { - html: `HTML Document`, + html: i18n('html_document'), icon: ``, onClick: async function(){ create_file({dirname: dirname, append_to_element: append_to_element, name: 'New File.html'}); @@ -58,7 +58,7 @@ const new_context_menu_item = function(dirname, append_to_element){ }, // JPG Image { - html: `JPG Image`, + html: i18n('jpeg_image'), icon: ``, onClick: async function(){ var canvas = document.createElement("canvas"); diff --git a/src/i18n/i18n.js b/src/i18n/i18n.js new file mode 100644 index 00000000..d69ea2cd --- /dev/null +++ b/src/i18n/i18n.js @@ -0,0 +1,477 @@ +window.locale = 'en'; + +window.i18n = function (key, replacements = [], encode_html = true) { + if(typeof replacements === 'boolean' && encode_html === undefined){ + encode_html = replacements; + replacements = []; + }else if(Array.isArray(replacements) === false){ + replacements = [replacements]; + } + + // if locale is not set, default to en + if(!window.translations[window.locale]) + window.locale = 'en'; + + let str = window.translations[window.locale][key]; + + if (!str) { + str = key; + } + str = encode_html ? html_encode(str) : str; + // replace %% occurrences with the values in replacements + // %% is for simple text replacements + // %strong% is for tags + // e.g. "Hello, %strong%" => "Hello, World" + // e.g. "Hello, %%" => "Hello, World" + // e.g. "Hello, %strong%, %%!" => "Hello, World, Universe!" + for (let i = 0; i < replacements.length; i++) { + // sanitize the replacement + replacements[i] = encode_html ? html_encode(replacements[i]) : replacements[i]; + // find first occurrence of %strong% + let index = str.indexOf('%strong%'); + // find first occurrence of %% + let index2 = str.indexOf('%%'); + // decide which one to replace + if (index === -1 && index2 === -1) { + break; + } else if (index === -1) { + str = str.replace('%%', replacements[i]); + } else if (index2 === -1) { + str = str.replace('%strong%', '' + replacements[i] + ''); + } else if (index < index2) { + str = str.replace('%strong%', '' + replacements[i] + ''); + } else { + str = str.replace('%%', replacements[i]); + } + } + return str; +} + +window.translations = { + en: { + access_granted_to: "Access Granted To", + add_existing_account: "Add Existing Account", + all_fields_required: 'All fields are required.', + apply: "Apply", + ascending: 'Ascending', + background: "Background", + browse: "Browse", + cancel: 'Cancel', + center: 'Center', + change_desktop_background: 'Change desktop background…', + change_password: "Change Password", + change_username: "Change Username", + close_all_windows: "Close All Windows", + color: 'Color', + confirm_account_for_free_referral_storage_c2a: 'Create an account and confirm your email address to receive 1 GB of free storage. Your friend will get 1 GB of free storage too.', + confirm_new_password: "Confirm New Password", + contact_us: "Contact Us", + contain: 'Contain', + continue: "Continue", + copy: 'Copy', + copy_link: "Copy Link", + copying: "Copying", + cover: 'Cover', + create_account: "Create Account", + create_free_account: "Create Free Account", + create_shortcut: "Create Shortcut", + current_password: "Current Password", + cut: 'Cut', + date_modified: 'Date modified', + delete: 'Delete', + delete_permanently: "Delete Permanently", + deploy_as_app: 'Deploy as app', + descending: 'Descending', + desktop_background_fit: "Fit", + dir_published_as_website: `%strong% has been published to:`, + disassociate_dir: "Disassociate Directory", + download: 'Download', + downloading: "Downloading", + email: "Email", + email_or_username: "Email or Username", + empty_trash: 'Empty Trash', + empty_trash_confirmation: `Are you sure you want to permanently delete the items in Trash?`, + emptying_trash: 'Emptying Trash…', + feedback: "Feedback", + feedback_c2a: "Please use the form below to send us your feedback, comments, and bug reports.", + feedback_sent_confirmation: "Thank you for contacting us. If you have an email associated with your account, you will hear back from us as soon as possible.", + forgot_pass_c2a: "Forgot password?", + from: "From", + general: "General", + get_a_copy_of_on_puter: `Get a copy of '%%' on Puter.com!`, + get_copy_link: 'Get Copy Link', + hide_all_windows: "Hide All Windows", + html_document: 'HTML document', + image: 'Image', + invite_link: "Invite Link", + items_in_trash_cannot_be_renamed: `This item can't be renamed because it's in the trash. To rename this item, first drag it out of the Trash.`, + jpeg_image: 'JPEG image', + keep_in_taskbar: 'Keep in Taskbar', + log_in: "Log In", + log_out: 'Log Out', + move: 'Move', + moving: "Moving", + my_websites: "My Websites", + name: 'Name', + name_cannot_be_empty: 'Name cannot be empty.', + name_cannot_contain_double_period: "Name can not be the '..' character.", + name_cannot_contain_period: "Name can not be the '.' character.", + name_cannot_contain_slash: "Name cannot contain the '/' character.", + name_must_be_string: "Name can only be a string.", + name_too_long: `Name can not be longer than %% characters.`, + new: 'New', + new_folder: 'New folder', + new_password: "New Password", + new_username: "New Username", + no_dir_associated_with_site: 'No directory associated with this address.', + no_websites_published: "You have not published any websites yet.", + ok: 'OK', + open: "Open", + open_in_new_tab: "Open in New Tab", + open_in_new_window: "Open in New Window", + open_with: "Open With", + password: "Password", + password_changed: "Password changed.", + passwords_do_not_match: '`New Password` and `Confirm New Password` do not match.', + paste: 'Paste', + paste_into_folder: "Paste Into Folder", + pick_name_for_website: "Pick a name for your website:", + picture: "Picture", + powered_by_puter_js: `Powered by Puter.js`, + preparing: "Preparing...", + preparing_for_upload: "Preparing for upload...", + properties: "Properties", + properties: 'Properties', + publish: "Publish", + publish_as_website: 'Publish as website', + recent: "Recent", + recover_password: "Recover Password", + refer_friends_c2a: "Get 1 GB for every friend who creates and confirms an account on Puter. Your friend will get 1 GB too!", + refer_friends_social_media_c2a: `Get 1 GB of free storage on Puter.com!`, + refresh: 'Refresh', + release_address_confirmation: `Are you sure you want to release this address?`, + remove_from_taskbar:'Remove from Taskbar', + rename: 'Rename', + repeat: 'Repeat', + resend_confirmation_code: "Re-send Confirmation Code", + restore: "Restore", + save_account_to_get_copy_link: "Please create an account to proceed.", + save_account_to_publish: 'Please create an account to proceed.', + save_session_c2a: 'Create an account to save your current session and avoid losing your work.', + scan_qr_c2a: 'Scan the code below to log into this session from other devices', + select: "Select", + select_color: 'Select color…', + send: "Send", + send_password_recovery_email: "Send Password Recovery Email", + session_saved: "Thank you for creating an account. This session has been saved.", + set_new_password: "Set New Password", + share_to: "Share to", + show_all_windows: "Show All Windows", + show_hidden: 'Show hidden', + sign_in_with_puter: "Sign in with Puter", + sign_up: "Sign Up", + signing_in: "Signing in…", + size: 'Size', + sort_by: 'Sort by', + start: 'Start', + taking_longer_than_usual: 'Taking a little longer than usual. Please wait...', + text_document: 'Text document', + tos_fineprint: `By clicking 'Create Free Account' you agree to Puter's Terms of Service and Privacy Policy.`, + trash: 'Trash', + type: 'Type', + undo: 'Undo', + unzip: "Unzip", + upload: 'Upload', + upload_here: 'Upload here', + username: "Username", + username_changed: 'Username updated successfully.', + versions: "Versions", + yes_release_it: 'Yes, Release It', + you_have_been_referred_to_puter_by_a_friend: "You have been referred to Puter by a friend!", + zip: "Zip", + }, + // korean + ko: { + access_granted_to: "접근 권한 부여", + add_existing_account: "기존 계정 추가", + all_fields_required: '모든 필드는 필수입니다.', + apply: "적용", + ascending: '오름차순', + background: "배경", + browse: "찾아보기", + cancel: '취소', + center: '중앙', + change_desktop_background: '바탕 화면 배경 변경…', + change_password: "비밀번호 변경", + change_username: "사용자 이름 변경", + close_all_windows: "모든 창 닫기", + color: '색상', + confirm_account_for_free_referral_storage_c2a: '계정을 생성하고 이메일 주소를 확인하여 1GB의 무료 저장 공간을 받으십시오. 친구도 1GB의 무료 저장 공간을 받게 됩니다.', + confirm_new_password: "새 비밀번호 확인", + contact_us: "문의하기", + contain: '포함', + continue: "계속", + copy: '복사', + copy_link: "링크 복사", + copying: "복사 중", + cover: '표지', + create_account: "계정 생성", + create_free_account: "무료 계정 생성", + create_shortcut: "바로 가기 만들기", + current_password: "현재 비밀번호", + cut: '잘라내기', + date_modified: '수정한 날짜', + delete: '삭제', + delete_permanently: "영구 삭제", + deploy_as_app: '앱으로 배포', + descending: '내림차순', + desktop_background_fit: "맞추기", + dir_published_as_website: `%strong% 다음에 게시되었습니다:`, + disassociate_dir: "디렉토리 연결 해제", + download: '다운로드', + downloading: "다운로드 중", + email: "이메일", + email_or_username: "이메일 또는 사용자 이름", + empty_trash: '휴지통 비우기', + empty_trash_confirmation: `휴지통의 항목을 영구적으로 삭제하시겠습니까?`, + emptying_trash: '휴지통 비우는 중…', + feedback: "피드백", + feedback_c2a: "아래 양식을 사용하여 피드백, 의견 및 버그 보고를 보내십시오.", + feedback_sent_confirmation: "문의해 주셔서 감사합니다. 계정에 이메일이 연결되어 있으면 가능한 빨리 회신 드리겠습니다.", + forgot_pass_c2a: "비밀번호를 잊으셨나요?", + from: "보낸 사람", + general: "일반", + get_a_copy_of_on_puter: `Puter.com에서 '%%'의 사본을 받으세요!`, + get_copy_link: '링크 복사', + hide_all_windows: "모든 창 숨기기", + html_document: 'HTML 문서', + image: '이미지', + invite_link: "초대 링크", + items_in_trash_cannot_be_renamed: `이 항목은 휴지통에 있기 때문에 이름을 바꿀 수 없습니다. 이 항목의 이름을 바꾸려면 먼저 휴지통에서 끌어내십시오.`, + jpeg_image: 'JPEG 이미지', + keep_in_taskbar: '작업 표시줄에 유지', + log_in: "로그인", + log_out: '로그아웃', + move: '이동', + moving: "이동 중", + my_websites: "내 웹사이트", + name: '이름', + name_cannot_be_empty: '이름은 비워둘 수 없습니다.', + name_cannot_contain_double_period: "이름은 '..' 문자일 수 없습니다.", + name_cannot_contain_period: "이름은 '.' 문자일 수 없습니다.", + name_cannot_contain_slash: "이름에 '/' 문자를 포함할 수 없습니다.", + name_must_be_string: "이름은 문자열만 가능합니다.", + name_too_long: `이름은 %%자보다 길 수 없습니다.`, + new: '새로운', + new_folder: '새 폴더', + new_password: "새 비밀번호", + new_username: "새 사용자 이름", + no_dir_associated_with_site: '이 주소에 연결된 디렉토리가 없습니다.', + no_websites_published: "아직 웹사이트를 게시하지 않았습니다.", + ok: '확인', + open: "열기", + open_in_new_tab: "새 탭에서 열기", + open_in_new_window: "새 창에서 열기", + open_with: "열기 방법", + password: "비밀번호", + password_changed: "비밀번호가 변경되었습니다.", + passwords_do_not_match: '`새 비밀번호`와 `새 비밀번호 확인`이 일치하지 않습니다.', + paste: '붙여넣기', + paste_into_folder: "폴더에 붙여넣기", + pick_name_for_website: "웹사이트 이름을 선택하세요:", + picture: "사진", + powered_by_puter_js: `Powered by Puter.js`, + preparing: "준비 중...", + preparing_for_upload: "업로드 준비 중...", + properties: "속성", + publish: "게시", + publish_as_website: '웹사이트로 게시', + recent: "최근", + recover_password: "비밀번호 찾기", + refer_friends_c2a: "Puter에서 계정을 생성하고 확인한 친구마다 1GB를 받으십시오. 친구도 1GB를 받게 됩니다!", + refer_friends_social_media_c2a: `Puter.com에서 1GB의 무료 저장 공간을 받으십시오!`, + refresh: '새로 고침', + release_address_confirmation: `이 주소를 해제하시겠습니까?`, + remove_from_taskbar:'작업 표시줄에서 제거', + rename: '이름 바꾸기', + repeat: '반복', + resend_confirmation_code: "확인 코드 다시 보내기", + restore: "복원", + save_account_to_get_copy_link: "계속하려면 계정을 생성하십시오.", + save_account_to_publish: '계속하려면 계정을 생성하십시오.', + save_session_c2a: '현재 세션을 저장하고 작업을 잃지 않으려면 계정을 생성하십시오.', + scan_qr_c2a: '다른 기기에서 이 세션으로 로그인하려면 아래 코드를 스캔하십시오', + select: "선택", + select_color: '색상 선택…', + send: "보내기", + send_password_recovery_email: "비밀번호 복구 이메일 보내기", + session_saved: "계정을 생성해 주셔서 감사합니다. 이 세션이 저장되었습니다.", + set_new_password: "새 비밀번호 설정", + share_to: "공유", + show_all_windows: "모든 창 표시", + show_hidden: '숨김 항목 표시', + sign_in_with_puter: "Puter로 로그인", + sign_up: "가입", + signing_in: "로그인 중…", + size: '크기', + sort_by: '정렬 기준', + start: '시작', + taking_longer_than_usual: '보통보다 조금 더 오래 걸립니다. 잠시만 기다려 주십시오...', + text_document: '텍스트 문서', + tos_fineprint: `무료 계정 생성을 클릭하면 Puter의 서비스 약관개인정보 보호정책에 동의하는 것입니다.`, + trash: '휴지통', + type: '유형', + undo: '실행 취소', + unzip: "압축 해제", + upload: '업로드', + upload_here: '여기에 업로드', + username: "사용자 이름", + username_changed: '사용자 이름이 성공적으로 업데이트되었습니다.', + versions: "버전", + yes_release_it: '예, 해제합니다', + you_have_been_referred_to_puter_by_a_friend: "친구가 Puter로 추천했습니다!", + zip: "압축", + }, + zh: { + access_granted_to: "访问授权给", + add_existing_account: "添加现有帐户", + all_fields_required: '所有字段都是必需的。', + apply: "应用", + ascending: '升序', + background: "背景", + browse: "浏览", + cancel: '取消', + center: '中心', + change_desktop_background: '更改桌面背景…', + change_password: "更改密码", + change_username: "更改用户名", + close_all_windows: "关闭所有窗口", + color: '颜色', + confirm_account_for_free_referral_storage_c2a: '创建帐户并确认您的电子邮件地址,以获得1 GB的免费存储空间。您的朋友也将获得1 GB的免费存储空间。', + confirm_new_password: "确认新密码", + contact_us: "联系我们", + contain: '包含', + continue: "继续", + copy: '复制', + copy_link: "复制链接", + copying: "复制", + cover: '封面', + create_account: "创建帐户", + create_free_account: "创建免费帐户", + create_shortcut: "创建快捷方式", + current_password: "当前密码", + cut: '剪切', + date_modified: '修改日期', + delete: '删除', + delete_permanently: "永久删除", + deploy_as_app: '部署为应用', + descending: '降序', + desktop_background_fit: "适合", + dir_published_as_website: `%strong% 已发布到:`, + disassociate_dir: "取消关联目录", + download: '下载', + downloading: "下载", + email: "电子邮件", + email_or_username: "电子邮件或用户名", + empty_trash: '清空回收站', + empty_trash_confirmation: `您确定要永久删除回收站中的项目吗?`, + emptying_trash: '清空回收站…', + feedback: "反馈", + feedback_c2a: "请使用下面的表格向我们发送您的反馈、评论和错误报告。", + feedback_sent_confirmation: "感谢您与我们联系。如果您的帐户关联有电子邮件,我们会尽快回复您。", + forgot_pass_c2a: "忘记密码?", + from: "从", + general: "一般", + get_a_copy_of_on_puter: `在 Puter.com 上获取 '%%' 的副本!`, + get_copy_link: '获取复制链接', + hide_all_windows: "隐藏所有窗口", + html_document: 'HTML 文档', + image: '图像', + invite_link: "邀请链接", + items_in_trash_cannot_be_renamed: `此项目无法重命名,因为它在回收站中。要重命名此项目,请先将其拖出回收站。`, + jpeg_image: 'JPEG 图像', + keep_in_taskbar: '保持在任务栏', + log_in: "登录", + log_out: '登出', + move: '移动', + moving: "移动", + my_websites: "我的网站", + name: '名称', + name_cannot_be_empty: '名称不能为空。', + name_cannot_contain_double_period: "名称不能是'..'字符。", + name_cannot_contain_period: "名称不能是'.'字符。", + name_cannot_contain_slash: "名称不能包含'/'字符。", + name_must_be_string: "名称只能是字符串。", + name_too_long: `名称不能超过 %% 个字符。`, + new: '新', + new_folder: '新文件夹', + new_password: "新密码", + new_username: "新用户名", + no_dir_associated_with_site: '此地址没有关联的目录。', + no_websites_published: "您尚未发布任何网站。", + ok: '好的', + open: "打开", + open_in_new_tab: "在新标签页中打开", + open_in_new_window: "在新窗口中打开", + open_with: "打开方式", + password: "密码", + password_changed: "密码已更改。", + passwords_do_not_match: '`新密码` 和 `确认新密码` 不匹配。', + paste: '粘贴', + paste_into_folder: "粘贴到文件夹", + pick_name_for_website: "为您的网站选择一个名称:", + picture: "图片", + powered_by_puter_js: `由 Puter.js 提供支持`, + preparing: "准备中...", + preparing_for_upload: "准备上传...", + properties: "属性", + properties: '属性', + publish: "发布", + publish_as_website: '发布为网站', + recent: "最近", + recover_password: "找回密码", + refer_friends_c2a: "每个创建并确认 Puter 帐户的朋友都会为您获得 1 GB。您的朋友也将获得 1 GB!", + refer_friends_social_media_c2a: `在 Puter.com 上获取 1 GB 的免费存储空间!`, + refresh: '刷新', + release_address_confirmation: `您确定要释放此地址吗?`, + remove_from_taskbar:'从任务栏中删除', + rename: '重命名', + repeat: '重复', + resend_confirmation_code: "重新发送确认码", + restore: "还原", + save_account_to_get_copy_link: "请创建帐户以继续。", + save_account_to_publish: '请创建帐户以继续。', + save_session_c2a: '创建帐户以保存当前会话,避免丢失工作。', + scan_qr_c2a: '扫描下面的代码以从其他设备登录此会话', + select: "选择", + select_color: '选择颜色…', + send: "发送", + send_password_recovery_email: "发送密码恢复电子邮件", + session_saved: "感谢您创建帐户。此会话已保存。", + set_new_password: "设置新密码", + share_to: "分享到", + show_all_windows: "显示所有窗口", + show_hidden: '显示隐藏', + sign_in_with_puter: "使用 Puter 登录", + sign_up: "注册", + signing_in: "登录中…", + size: '大小', + sort_by: '排序方式', + start: '开始', + taking_longer_than_usual: '需要的时间比平时长一点。请稍等...', + text_document: '文本文档', + tos_fineprint: `点击“创建免费帐户”即表示您同意 Puter 的 服务条款隐私政策。`, + trash: '回收站', + type: '类型', + undo: '撤销', + unzip: "解压缩", + upload: '上传', + upload_here: '在此上传', + username: "用户名", + username_changed: '用户名已成功更新。', + versions: "版本", + yes_release_it: '是的,释放它', + you_have_been_referred_to_puter_by_a_friend: "您已经被朋友推荐到 Puter!", + zip: "压缩", + }, +} \ No newline at end of file diff --git a/src/initgui.js b/src/initgui.js index eada45ff..0295dcc8 100644 --- a/src/initgui.js +++ b/src/initgui.js @@ -46,6 +46,10 @@ window.initgui = async function(){ if(window.api_origin && puter.APIOrigin !== window.api_origin) puter.setAPIOrigin(api_origin); + // determine locale + // const userLang = navigator.language || navigator.userLanguage || 'en'; + // window.locale = userLang?.split('-')[0] ?? 'en'; + window.locale = 'ko'; // Checks the type of device the user is on (phone, tablet, or desktop). // Depending on the device type, it sets a class attribute on the body tag // to style or script the page differently for each device type. diff --git a/src/static-assets.js b/src/static-assets.js index da8d50a0..481d2270 100644 --- a/src/static-assets.js +++ b/src/static-assets.js @@ -33,6 +33,7 @@ const lib_paths =[ `/lib/iro.min.js`, `/lib/isMobile.min.js`, `/lib/jszip-3.10.1.min.js`, + `/i18n/i18n.js`, ] // Ordered list of CSS stylesheets