diff --git a/src/UI/Settings/UIWindowSettings.js b/src/UI/Settings/UIWindowSettings.js new file mode 100644 index 00000000..ae53dbb0 --- /dev/null +++ b/src/UI/Settings/UIWindowSettings.js @@ -0,0 +1,415 @@ +/** + * Copyright (C) 2024 Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import UIWindow from '../UIWindow.js' +import UIWindowChangePassword from '../UIWindowChangePassword.js' +// import UIWindowChangeEmail from './UIWindowChangeEmail.js' +// import UIWindowDeleteAccount from './UIWindowDeleteAccount.js' +import UIWindowChangeUsername from '../UIWindowChangeUsername.js' +import changeLanguage from "../../i18n/i18nchangeLanguage.js" + + +async function UIWindowSettings(options){ + return new Promise(async (resolve) => { + options = options ?? {}; + + let h = ''; + + h += `
`; + h += `
`; + // side bar + h += `
`; + h += `
${i18n('about')}
`; + h += `
${i18n('usage')}
`; + h += `
${i18n('account')}
`; + h += `
${i18n('language')}
`; + h += `
`; + + // content + h += `
`; + // About + h += `
`; + h += `
` + h += `
+ +

Puter is a privacy-first personal cloud to keep all your files, apps, and games in one + secure place, accessible from anywhere at any time.

+ + +
+
+ + +
+

Open Source Software and Content

+
+ +
+
+
+ `; + h += `
`; + h += `
`; + + // Usage + h += `
`; + h += `

Usage

`; + h += `
+

Storage Usage

+
+ + used of + +
+
+ +
+
+
` + h += `
`; + + // Account + h += `
`; + h += `

Account

`; + // change password button + h += `
`; + h += `Password`; + h += `
`; + h += ``; + h += `
`; + h += `
`; + + // change email button + if(user.email){ + h += `
`; + h += `${user.email}`; + h += `
`; + h += ``; + h += `
`; + h += `
`; + } + + // change username button + h += `
`; + h += `
`; + h += `Username`; + h += `${user.username}`; + h += `
`; + h += `
`; + h += ``; + h += `
` + h += `
`; + + // delete account button + h += `
`; + h += `Delete Account`; + h += `
`; + h += ``; + h += `
`; + h += `
`; + + h += `
`; + + // Language + h += `
`; + h += `

Language

`; + // search + h += `
`; + h += ``; + h += `
`; + // list of languages + const available_languages = listSupportedLanguages(); + h += `
`; + for (let lang of available_languages) { + h += `
${lang.name}
`; + } + h += `
`; + + h += `
`; + + h += `
`; + h += `
`; + h += `
`; + + h += ``; + + const el_window = await UIWindow({ + title: 'Settings', + app: 'settings', + single_instance: true, + icon: null, + uid: null, + is_dir: false, + body_content: h, + has_head: true, + selectable_body: false, + allow_context_menu: false, + is_resizable: false, + is_droppable: false, + init_center: true, + allow_native_ctxmenu: true, + allow_user_select: true, + backdrop: false, + width: 800, + height: 500, + height: 'auto', + dominant: true, + show_in_taskbar: false, + draggable_body: false, + onAppend: function(this_window){ + }, + window_class: 'window-settings', + body_css: { + width: 'initial', + height: '100%', + overflow: 'auto' + } + }); + + $.ajax({ + url: api_origin + "/drivers/usage", + type: 'GET', + async: true, + contentType: "application/json", + headers: { + "Authorization": "Bearer " + auth_token + }, + statusCode: { + 401: function () { + logout(); + }, + }, + success: function (res) { + let h = ''; // Initialize HTML string for driver usage bars + + // Loop through user services + res.user.forEach(service => { + const { monthly_limit, monthly_usage } = service; + let usageDisplay = ``; + + if (monthly_limit !== null) { + let usage_percentage = (monthly_usage / monthly_limit * 100).toFixed(0); + usage_percentage = usage_percentage > 100 ? 100 : usage_percentage; // Cap at 100% + usageDisplay = ` +
+

${service.service['driver.interface']} (${service.service['driver.method']}):

+ ${monthly_usage} used of ${monthly_limit} +
+
${usage_percentage}%
+
+
+ `; + } + else { + usageDisplay = ` +
+

${service.service['driver.interface']} (${service.service['driver.method']}):

+ Usage: ${monthly_usage} (Unlimited) +
+ `; + } + h += usageDisplay; + }); + + // Append driver usage bars to the container + $('.settings-content[data-settings="usage"]').append(`
${h}
`); + } + }) + + // df + $.ajax({ + url: api_origin + "/df", + type: 'GET', + async: true, + contentType: "application/json", + headers: { + "Authorization": "Bearer " + auth_token + }, + statusCode: { + 401: function () { + logout(); + }, + }, + success: function (res) { + let usage_percentage = (res.used / res.capacity * 100).toFixed(0); + usage_percentage = usage_percentage > 100 ? 100 : usage_percentage; + + $('#storage-used').html(byte_format(res.used)); + $('#storage-capacity').html(byte_format(res.capacity)); + $('#storage-used-percent').html(usage_percentage + '%'); + $('#storage-bar').css('width', usage_percentage + '%'); + if (usage_percentage >= 100) { + $('#storage-bar').css({ + 'border-top-right-radius': '3px', + 'border-bottom-right-radius': '3px', + }); + } + } + }) + + // version + $.ajax({ + url: api_origin + "/version", + type: 'GET', + async: true, + contentType: "application/json", + headers: { + "Authorization": "Bearer " + auth_token + }, + statusCode: { + 401: function () { + logout(); + }, + }, + success: function (res) { + var d = new Date(0); + $('.version').html('Version: ' + res.version + ' • ' + 'Server: ' + res.location + ' • ' + 'Deployed: ' + new Date(res.deploy_timestamp)); + } + }) + + $(el_window).find('.credits').on('click', function (e) { + if($(e.target).hasClass('credits')){ + $('.credits').get(0).close(); + } + }); + + $(el_window).find('.show-credits').on('click', function (e) { + $('.credits').get(0).showModal(); + }) + + $(el_window).find('.change-password').on('click', function (e) { + UIWindowChangePassword(); + }) + + $(el_window).find('.change-email').on('click', function (e) { + UIWindowChangeEmail(); + }) + + $(el_window).find('.delete-account').on('click', function (e) { + UIWindowDeleteAccount(); + }) + + $(el_window).find('.change-username').on('click', function (e) { + UIWindowChangeUsername(); + }) + + $(el_window).on('click', '.settings-sidebar-item', function(){ + const $this = $(this); + const settings = $this.attr('data-settings'); + const $container = $this.closest('.settings').find('.settings-content-container'); + const $content = $container.find(`.settings-content[data-settings="${settings}"]`); + // add active class to sidebar item + $this.siblings().removeClass('active'); + $this.addClass('active'); + // add active class to content + $container.find('.settings-content').removeClass('active'); + $content.addClass('active'); + // if language, focus on search + if(settings === 'language'){ + $content.find('.search').first().focus(); + // make sure all language items are visible + $content.find('.language-item').show(); + // empty search + $content.find('.search').val(''); + } + }) + + $(el_window).on('click', '.language-item', function(){ + const $this = $(this); + const lang = $this.attr('data-lang'); + changeLanguage(lang); + $this.siblings().removeClass('active'); + $this.addClass('active'); + // make sure all other language items are visible + $this.closest('.language-list').find('.language-item').show(); + }) + + $(el_window).on('input', '.search', function(){ + const $this = $(this); + const search = $this.val().toLowerCase(); + const $container = $this.closest('.settings').find('.settings-content-container'); + const $content = $container.find('.settings-content.active'); + const $list = $content.find('.language-list'); + const $items = $list.find('.language-item'); + $items.each(function(){ + const $item = $(this); + const lang = $item.attr('data-lang'); + const name = $item.text().toLowerCase(); + const english_name = $item.attr('data-english-name').toLowerCase(); + if(name.includes(search) || lang.includes(search) || english_name.includes(search)){ + $item.show(); + }else{ + $item.hide(); + } + }) + }); + + resolve(el_window); + }); +} + + +export default UIWindowSettings \ No newline at end of file diff --git a/src/UI/UIDesktop.js b/src/UI/UIDesktop.js index 18ad3251..4281fb18 100644 --- a/src/UI/UIDesktop.js +++ b/src/UI/UIDesktop.js @@ -34,7 +34,8 @@ import UIWindowQR from "./UIWindowQR.js" import UIWindowRefer from "./UIWindowRefer.js" import UITaskbar from "./UITaskbar.js" import new_context_menu_item from "../helpers/new_context_menu_item.js" -import ChangeLanguage from "../i18n/i18nChangeLanguage.js" +import changeLanguage from "../i18n/i18nchangeLanguage.js" +import UIWindowSettings from "./Settings/UIWindowSettings.js" async function UIDesktop(options){ let h = ''; @@ -1156,12 +1157,12 @@ $(document).on('click', '.user-options-menu-btn', async function(e){ // ------------------------------------------- // Load available languages // ------------------------------------------- - const supportedLanguagesItems = ListSupportedLanguages().map(lang => { + const supportedLanguagesItems = listSupportedLanguages().map(lang => { return { html: lang.name, icon: window.locale === lang.code ? '✓' : '', onClick: async function(){ - ChangeLanguage(lang.code); + changeLanguage(lang.code); } } }); @@ -1288,10 +1289,7 @@ $(document).on('click', '.close-launch-popover', function(){ }); $(document).on('click', '.toolbar-puter-logo', function(){ - // launch the about app - launch_app({name: 'about', window_options:{ - single_instance: true, - }}); + UIWindowSettings(); }) $(document).on('click', '.user-options-create-account-btn', async function(e){ diff --git a/src/css/style.css b/src/css/style.css index 5dd97c1e..0950031d 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -2138,7 +2138,7 @@ label { font: 14px "Helvetica Neue", Sans-Serif; border: none !important; backdrop-filter: blur(3px); - filter: drop-shadow(0 0 3px rgba(0,0,0,.455)); + filter: drop-shadow(0 0 3px rgba(0, 0, 0, .455)); } .arrow { @@ -3254,4 +3254,299 @@ label { justify-content: center; align-items: center; display: none; +} + +/*! + * ================================================== + * Settings + * ================================================== + */ + +.settings-container{ + display: flex; + flex-direction: column; + height: 100%; +} +.settings{ + display: flex; + flex-direction: row; + -webkit-font-smoothing: antialiased; + flex-grow: 1; +} + +.settings-sidebar{ + width: 200px; + background-color: #f9f9f9; + border-right: 1px solid #e0e0e0; + padding: 20px; + +} + +.settings-sidebar-item{ + cursor: pointer; + border-radius: 4px; + padding: 10px; + margin-bottom: 15px; + background-repeat: no-repeat; + background-position: 10px center; + background-size: 25px; + padding-left: 45px; + font-size: 15px; +} +.settings-sidebar-item:hover{ + background-color: #e8e8e8; +} + +.settings-sidebar-item.active{ + background-color: #e0e0e0; +} +.settings-content-container{ + flex: 1; + padding: 20px 30px; + height: 500px; + overflow-y: scroll; +} + +.settings-content{ + display: none; +} + +.settings-content[data-settings="about"]{ + height: 100%; +} + +.settings-content h1{ + font-size: 24px; + margin-bottom: 20px; + border-bottom: 1px solid #e0e0e0; + padding-bottom: 10px; + padding-left: 5px; + font-weight: 500; +} + +.settings-content.active{ + display: block; +} + +.settings-content .about-container{ + height: 100%; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; +} +.settings-content[data-settings="about"] a { + color: #1663d4; + text-decoration: none; + font-size: 12px; +} + +.settings-content[data-settings="about"] a:hover { + text-decoration: underline; +} + +.settings-content .logo, +.settings-content .logo img { + display: block; + width: 55px; + height: 55px; + margin: 0 auto; + border-radius: 4px; +} + +.settings-content .links { + text-align: center; + font-size: 14px; + margin-top: 10px; +} + +.settings-content .social-links { + text-align: center; + /* margin-top: 10px; */ +} + +.settings-content .social-links a { + opacity: 0.7; + transition: opacity 0.1s ease-in-out; +} + +.settings-content .social-links a, +.settings-content .social-links a:hover { + text-decoration: none; + margin: 0 10px; + +} + +.settings-content .social-links a:hover { + opacity: 1; +} + +.settings-content .social-links svg { + width: 20px; + height: 20px; +} + +.settings-content .about { + text-align: center; + display: flex; + flex-direction: column; + justify-content: center; + padding: 20px 40px; + max-width: 500px; +} +.settings-content .version{ + font-size: 9px; + color: #343c4f; + text-align: center; + margin-bottom: 10px; + opacity: 0.3; + transition: opacity 0.1s ease-in-out; + height: 12px; +} +.settings-content .version:hover{ + opacity: 1; +} + +.driver-usage { + background-color: white; + bottom: 0; + width: 100%; + box-sizing: border-box; + color: #3c4963; + height: 85px; +} +.credits{ + padding: 0; + border: 1px solid #bfbfbf; + box-shadow: 1px 1px 10px 0px #8a8a8a; + width: 400px; +} +.credit-content a{ + font-size:15px; +} +.credits .credit-content{ + padding: 20px; +} +.credit-content{ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.credit-content ul{ + max-height: 300px; + overflow-y: scroll; + background: #f4f4f4; + padding: 10px; + box-shadow: 2px 2px 5px 2px inset #CCC; + +} +.credit-content li{ + margin-bottom: 10px; +} +#storage-bar-wrapper { + width: 100%; + height: 15px; + border: 1px solid #8a9096; + border-radius: 3px; + background-color: #fff; + position: relative; +} + +#storage-bar { + height: 15px; + background-color: #dbe3ef; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + width: 0; +} + +#storage-used-percent { + position: absolute; + left: calc(50% - 20px); + text-align: center; + display: inline-block; + width: 40px; + font-size: 13px; +} + +.usage-progbar-wrapper { + width: 100%; + height: 15px; + border: 1px solid #8a9096; + border-radius: 3px; + background-color: #fff; + position: relative; +} + +.usage-progbar { + height: 15px; + background-color: #dbe3ef; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + width: 0; +} + +.usage-progbar-percent { + position: absolute; + left: calc(50% - 20px); + text-align: center; + display: inline-block; + width: 40px; + font-size: 13px; +} + + +.version{ + font-size: 9px; + color: #343c4f; + text-align: center; + margin-bottom: 10px; + opacity: 0.3; + transition: opacity 0.1s ease-in-out; + height: 12px; +} +.version:hover{ + opacity: 1; +} +.language-list{ + display: grid; + grid-template-columns: 33.333333333% 33.333333333% 33.333333333%; +} +.language-item{ + cursor: pointer; + padding: 10px; + border-radius: 4px; + margin-bottom: 10px; + margin-right: 10px; +} + +.language-item:hover{ + background-color: #f6f6f6; +} + +.language-item.active{ + background-color: #e0e0e0; +} + +.settings-card{ + overflow: hidden; + padding: 10px 15px; + border: 1px solid; + border-radius: 4px; + background: #f7f7f7a1; + border: 1px solid #cccccc8f; + margin-bottom: 20px; + display: flex; + flex-direction: row; + align-items: center; + height: 45px; +} + +.settings-card strong{ + font-weight: 500; +} + +.settings-card-danger{ + border-color: #f0080866; + background: #ffecec; + color: rgb(215 2 2); } \ No newline at end of file diff --git a/src/globals.js b/src/globals.js index fb69918b..97d1251a 100644 --- a/src/globals.js +++ b/src/globals.js @@ -220,4 +220,7 @@ window.feature_flags = { window.is_auto_arrange_enabled = true; window.desktop_item_positions = {}; -window.reset_item_positions = true; // The variable decides if the item positions should be reset when the user enabled auto arrange \ No newline at end of file +window.reset_item_positions = true; // The variable decides if the item positions should be reset when the user enabled auto arrange + +// default language +window.locale = 'en'; \ No newline at end of file diff --git a/src/helpers.js b/src/helpers.js index 96b13a23..cf352459 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -722,7 +722,7 @@ window.mutate_user_preferences = function(user_preferences_delta) { window.update_user_preferences = function(user_preferences) { window.user_preferences = user_preferences; localStorage.setItem('user_preferences', JSON.stringify(user_preferences)); - window.locale = user_preferences.language; + window.locale = user_preferences.language ?? 'en'; } window.sendWindowWillCloseMsg = function(iframe_element) { diff --git a/src/i18n/i18n.js b/src/i18n/i18n.js index 14b46873..5503a293 100644 --- a/src/i18n/i18n.js +++ b/src/i18n/i18n.js @@ -18,7 +18,7 @@ */ import translations from './translations/translations.js'; -window.ListSupportedLanguages = () => Object.keys(translations).map(lang => translations[lang]); +window.listSupportedLanguages = () => Object.keys(translations).map(lang => translations[lang]); window.i18n = function (key, replacements = [], encode_html = true) { if(typeof replacements === 'boolean' && encode_html === undefined){ diff --git a/src/i18n/i18nChangeLanguage.js b/src/i18n/i18nChangeLanguage.js index e3482daf..44cfa335 100644 --- a/src/i18n/i18nChangeLanguage.js +++ b/src/i18n/i18nChangeLanguage.js @@ -17,11 +17,11 @@ * along with this program. If not, see . */ -function ChangeLanguage(lang) { +function changeLanguage(lang) { window.locale = lang; window.mutate_user_preferences({ language : lang, }); } -export default ChangeLanguage; \ No newline at end of file +export default changeLanguage; \ No newline at end of file diff --git a/src/i18n/translations/ar.js b/src/i18n/translations/ar.js index ea51c9d4..279d8119 100644 --- a/src/i18n/translations/ar.js +++ b/src/i18n/translations/ar.js @@ -18,6 +18,7 @@ */ const ar = { name: "العربية", + english_name: "Arabic", code: "ar", dictionary: { access_granted_to: "دخول مسموح به", diff --git a/src/i18n/translations/bn.js b/src/i18n/translations/bn.js index 2bd82522..8cc68092 100644 --- a/src/i18n/translations/bn.js +++ b/src/i18n/translations/bn.js @@ -18,6 +18,7 @@ */ const bn = { name: "বাংলা", + english_name: "Bengali", code: "bn", dictionary: { access_granted_to: "অ্যাক্সেস মঞ্জুর করা হয়েছে", diff --git a/src/i18n/translations/da.js b/src/i18n/translations/da.js index ca72769e..21f9ab30 100644 --- a/src/i18n/translations/da.js +++ b/src/i18n/translations/da.js @@ -18,6 +18,7 @@ */ const da = { name: "Dansk", + english_name: "Danish", code: "da", dictionary: { access_granted_to: "Adgang givet til", diff --git a/src/i18n/translations/de.js b/src/i18n/translations/de.js index 7a750370..5f665b8c 100644 --- a/src/i18n/translations/de.js +++ b/src/i18n/translations/de.js @@ -18,6 +18,7 @@ */ const de = { name: "Deutsch", + english_name: "German", code: "de", dictionary: { access_granted_to: "Erlaubt zugriff auf", diff --git a/src/i18n/translations/emoji.js b/src/i18n/translations/emoji.js index 0ec22b53..dfa41ee4 100644 --- a/src/i18n/translations/emoji.js +++ b/src/i18n/translations/emoji.js @@ -18,6 +18,7 @@ */ const emoji = { name: "🌍", + english_name: "Emoji", code: "emoji", dictionary: { access_granted_to: "🔓✅", diff --git a/src/i18n/translations/en.js b/src/i18n/translations/en.js index 706d765d..88fcf2ef 100644 --- a/src/i18n/translations/en.js +++ b/src/i18n/translations/en.js @@ -18,8 +18,11 @@ */ const en = { name: "English", + english_name: "English", code: "en", dictionary: { + about: "About", + account: "Account", access_granted_to: "Access Granted To", add_existing_account: "Add Existing Account", all_fields_required: 'All fields are required.', @@ -87,6 +90,7 @@ const en = { 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', + language: "Language", loading: 'Loading', log_in: "Log In", log_into_another_account_anyway: 'Log into another account anyway', @@ -173,6 +177,7 @@ const en = { unzip: "Unzip", upload: 'Upload', upload_here: 'Upload here', + usage: 'Usage', username: "Username", username_changed: 'Username updated successfully.', versions: "Versions", diff --git a/src/i18n/translations/es.js b/src/i18n/translations/es.js index 82005c4e..e6ccca5b 100644 --- a/src/i18n/translations/es.js +++ b/src/i18n/translations/es.js @@ -18,6 +18,7 @@ */ const es = { name: "Español", + english_name: "Spanish", code: "es", dictionary: { access_granted_to: "Acceso Permitido A", diff --git a/src/i18n/translations/fa.js b/src/i18n/translations/fa.js index 10068094..e2d3b94d 100644 --- a/src/i18n/translations/fa.js +++ b/src/i18n/translations/fa.js @@ -18,6 +18,7 @@ */ const fa = { name: "فارسی", + english_name: "Farsi", code: "fa", dictionary: { access_granted_to: "دسترسی داده شده به", diff --git a/src/i18n/translations/fi.js b/src/i18n/translations/fi.js index d43d0753..9950f10f 100644 --- a/src/i18n/translations/fi.js +++ b/src/i18n/translations/fi.js @@ -18,6 +18,7 @@ */ const fi = { name: "Suomi", + english_name: "Finnish", code: "fi", dictionary: { access_granted_to: "Käyttöoikeus Myönnetty", diff --git a/src/i18n/translations/fr.js b/src/i18n/translations/fr.js index 1ce604af..bff28b64 100644 --- a/src/i18n/translations/fr.js +++ b/src/i18n/translations/fr.js @@ -18,6 +18,7 @@ */ const fr = { name: "Français", + english_name: "French", code: "fr", dictionary: { access_granted_to: "Accès accordé à", diff --git a/src/i18n/translations/hy.js b/src/i18n/translations/hy.js index 1388753b..01c4d6cc 100644 --- a/src/i18n/translations/hy.js +++ b/src/i18n/translations/hy.js @@ -18,6 +18,7 @@ */ const hy = { name: "Հայերեն", + english_name: "Armenian", code: "hy", dictionary: { access_granted_to: "Մուտքը տրված է՝", diff --git a/src/i18n/translations/it.js b/src/i18n/translations/it.js index c967671b..abace233 100644 --- a/src/i18n/translations/it.js +++ b/src/i18n/translations/it.js @@ -18,6 +18,7 @@ */ const it = { name: "Italiano", + english_name: "Italian", code: "it", dictionary: { access_granted_to: "Accesso garantito a", diff --git a/src/i18n/translations/ko.js b/src/i18n/translations/ko.js index 517b264e..6ec427e2 100644 --- a/src/i18n/translations/ko.js +++ b/src/i18n/translations/ko.js @@ -18,6 +18,7 @@ */ const ko = { name: "한국어", + english_name: "Korean", code: "ko", dictionary: { access_granted_to: "접근 권한 부여", diff --git a/src/i18n/translations/nb.js b/src/i18n/translations/nb.js index b5e309ff..50bfbe83 100644 --- a/src/i18n/translations/nb.js +++ b/src/i18n/translations/nb.js @@ -18,6 +18,7 @@ */ const nb = { name: "Norsk Bokmål", + english_name: "Norwegian Bokmål", code: "nb", dictionary: { access_granted_to: "Tilgang gitt til", diff --git a/src/i18n/translations/nn.js b/src/i18n/translations/nn.js index a4298e5b..471762ea 100644 --- a/src/i18n/translations/nn.js +++ b/src/i18n/translations/nn.js @@ -18,6 +18,7 @@ */ const nn = { name: "Norsk Nynorsk", + english_name: "Norwegian Nynorsk", code: "nn", dictionary: { access_granted_to: "Tilgang gjeven til", diff --git a/src/i18n/translations/ro.js b/src/i18n/translations/ro.js index 14adabba..feaa56b7 100644 --- a/src/i18n/translations/ro.js +++ b/src/i18n/translations/ro.js @@ -18,6 +18,7 @@ */ const ro = { name: "Română", + english_name: "Romanian", code: "ro", dictionary: { access_granted_to: "Acces acordat pentru", diff --git a/src/i18n/translations/sv.js b/src/i18n/translations/sv.js index 30f3c700..6136cdfb 100644 --- a/src/i18n/translations/sv.js +++ b/src/i18n/translations/sv.js @@ -18,6 +18,7 @@ */ const sv = { name: "Svenska", + english_name: "Swedish", code: "sv", dictionary: { access_granted_to: "Tillgång beviljad till", diff --git a/src/i18n/translations/th.js b/src/i18n/translations/th.js index f369143f..99383292 100644 --- a/src/i18n/translations/th.js +++ b/src/i18n/translations/th.js @@ -18,6 +18,7 @@ */ const th = { name: "ไทย", + english_name: "Thai", code: "th", dictionary: { access_granted_to: "อนุญาตให้เข้าถึง", diff --git a/src/i18n/translations/ur.js b/src/i18n/translations/ur.js index cfa51332..65c79eaf 100644 --- a/src/i18n/translations/ur.js +++ b/src/i18n/translations/ur.js @@ -18,6 +18,7 @@ */ const ur = { name: "اردو", + english_name: "Urdu", code: "ur", dictionary: { access_granted_to: "رسائی مسموح ہے", diff --git a/src/i18n/translations/zh.js b/src/i18n/translations/zh.js index 7066a4d0..82e44ab0 100644 --- a/src/i18n/translations/zh.js +++ b/src/i18n/translations/zh.js @@ -18,6 +18,7 @@ */ const zh = { name: "中文", + english_name: "Chinese", code: "zh", dictionary: { access_granted_to: "访问授权给", diff --git a/src/icons/cube-outline.svg b/src/icons/cube-outline.svg new file mode 100644 index 00000000..77faf2a5 --- /dev/null +++ b/src/icons/cube-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/language.svg b/src/icons/language.svg new file mode 100644 index 00000000..67a1c09f --- /dev/null +++ b/src/icons/language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/logo-outline.svg b/src/icons/logo-outline.svg new file mode 100644 index 00000000..397bb720 --- /dev/null +++ b/src/icons/logo-outline.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/icons/palette-fill.svg b/src/icons/palette-fill.svg new file mode 100644 index 00000000..d7a6a3bc --- /dev/null +++ b/src/icons/palette-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/icons/palette-outline.svg b/src/icons/palette-outline.svg new file mode 100644 index 00000000..0ab25d65 --- /dev/null +++ b/src/icons/palette-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/speedometer-outline.svg b/src/icons/speedometer-outline.svg new file mode 100644 index 00000000..75e79c85 --- /dev/null +++ b/src/icons/speedometer-outline.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/icons/user.svg b/src/icons/user.svg new file mode 100644 index 00000000..a7b32245 --- /dev/null +++ b/src/icons/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/logo.png b/src/images/logo.png new file mode 100644 index 00000000..56603cba Binary files /dev/null and b/src/images/logo.png differ