Merge branch 'develop' into feature/asset-qortalrequests
@ -2,17 +2,17 @@ module.exports = {
|
||||
root: true,
|
||||
env: { browser: true, es2020: true },
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:react-hooks/recommended",
|
||||
],
|
||||
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['react-refresh'],
|
||||
ignorePatterns: ["dist", ".eslintrc.cjs"],
|
||||
parser: "@typescript-eslint/parser",
|
||||
plugins: ["react-refresh"],
|
||||
rules: {
|
||||
'react-refresh/only-export-components': [
|
||||
'off',
|
||||
"react-refresh/only-export-components": [
|
||||
"off",
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
},
|
||||
}
|
||||
};
|
||||
|
1
.gitignore
vendored
@ -9,6 +9,7 @@ lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist.zip
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
|
3
.prettierignore
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
build
|
||||
dist
|
23
.prettierrc
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"arrowParens": "always",
|
||||
"bracketSameLine": false,
|
||||
"bracketSpacing": true,
|
||||
"embeddedLanguageFormatting": "auto",
|
||||
"endOfLine": "lf",
|
||||
"experimentalTernaries": false,
|
||||
"htmlWhitespaceSensitivity": "css",
|
||||
"insertPragma": false,
|
||||
"jsxBracketSameLine": false,
|
||||
"jsxSingleQuote": false,
|
||||
"printWidth": 80,
|
||||
"proseWrap": "preserve",
|
||||
"quoteProps": "as-needed",
|
||||
"requirePragma": false,
|
||||
"semi": true,
|
||||
"singleAttributePerLine": false,
|
||||
"singleQuote": true,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5",
|
||||
"useTabs": false,
|
||||
"vueIndentScriptAndStyle": false
|
||||
}
|
14
README.md
@ -1,6 +1,6 @@
|
||||
# Qortal Hub - Desktop Interface for Qortal
|
||||
|
||||
Qortal Hub is the newest interface for Qortal, part of the 'Qortal Trifecta' series of new User Interfaces for the platform/network.
|
||||
Qortal Hub is the newest interface for Qortal, part of the 'Qortal Trifecta' series of new User Interfaces for the platform/network.
|
||||
|
||||
It is likely that Qortal Hub will become the new 'primary interface' for Qortal, and that the primary development focus surrounding Qortal Interface development, will be focused here instead of the previous 'qortal-ui' repo.
|
||||
|
||||
@ -8,14 +8,20 @@ It is likely that Qortal Hub will become the new 'primary interface' for Qortal,
|
||||
|
||||
Qortal Hub came along with the new Group Encryption methodologies applied, which provide **encrypted chat in Q-Chat for private groups.** Qortal Hub was the first to implement the new method of group encryption, which allows new users to see previously published data, unlike the previous group encryption methodology of things like 'threads' in Q-Mail.
|
||||
|
||||
Allowing new users to view older messages also comes along with a massive boost to the usability of the group encryption, and as such has been leveraged in multiple places inside Qortal Hub, Qortal Extension, and Qortal Go.
|
||||
Allowing new users to view older messages also comes along with a massive boost to the usability of the group encryption, and as such has been leveraged in multiple places inside Qortal Hub, Qortal Extension, and Qortal Go.
|
||||
|
||||
## Ease of Use Expanded
|
||||
|
||||
Qortal Hub has a focus on ease of use for new users. Providing both the ability to utlilize Qortal without needing to run a local node (though running a local node is still the recommended method to access Qortal), and multiple built-in (QDN-published) walk-thru videos (by Qortal Justin) that explain the various basics of any given section of the application. This allows new users to 'jump right in' to utilizing Qortal Hub, and Qortal overall, in a much more streamlined fashion than that which was previously required by the 'legacy UI' (qortal-ui).
|
||||
Qortal Hub has a focus on ease of use for new users. Providing both the ability to utlilize Qortal without needing to run a local node (though running a local node is still the recommended method to access Qortal), and multiple built-in (QDN-published) walk-thru videos (by Qortal Justin) that explain the various basics of any given section of the application. This allows new users to 'jump right in' to utilizing Qortal Hub, and Qortal overall, in a much more streamlined fashion than that which was previously required by the 'legacy UI' (qortal-ui).
|
||||
|
||||
Leveraging a redundant set of publicly accessible nodes provided by crowetic, Qortal Hub, Qortal Go, and Qortal Extension, all allow the use of Qortal without running a node, making it very simple to 'install and go' and start making use of the extensive functionality provided within the Qortal Ecosystem.
|
||||
Leveraging a redundant set of publicly accessible nodes provided by crowetic, Qortal Hub, Qortal Go, and Qortal Extension, all allow the use of Qortal without running a node, making it very simple to 'install and go' and start making use of the extensive functionality provided within the Qortal Ecosystem.
|
||||
|
||||
Many additional details and a fully featured wiki will be created over time. Reach out on the chat on https://qortal.dev or in any of the community locations for Qortal, if you have any issues. Thank you!
|
||||
|
||||
## Internationalization (i18n)
|
||||
|
||||
Qortal-Hub supports internationalization (i18n) using [i18next](https://www.i18next.com/), allowing seamless translation of UI text into multiple languages.
|
||||
The setup includes modularized translation files, language detection, context and runtime language switching.
|
||||
Files with translation are in `public/locales/<locale>` folder.
|
||||
|
||||
See [guidelines](./docs/i18n_languages.md).
|
||||
|
101
android/.gitignore
vendored
@ -1,101 +0,0 @@
|
||||
# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore
|
||||
|
||||
# Built application files
|
||||
*.apk
|
||||
*.aar
|
||||
*.ap_
|
||||
*.aab
|
||||
|
||||
# Files for the ART/Dalvik VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# Generated files
|
||||
bin/
|
||||
gen/
|
||||
out/
|
||||
# Uncomment the following line in case you need and you don't have the release build type files in your app
|
||||
# release/
|
||||
|
||||
# Gradle files
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Proguard folder generated by Eclipse
|
||||
proguard/
|
||||
|
||||
# Log Files
|
||||
*.log
|
||||
|
||||
# Android Studio Navigation editor temp files
|
||||
.navigation/
|
||||
|
||||
# Android Studio captures folder
|
||||
captures/
|
||||
|
||||
# IntelliJ
|
||||
*.iml
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/gradle.xml
|
||||
.idea/assetWizardSettings.xml
|
||||
.idea/dictionaries
|
||||
.idea/libraries
|
||||
# Android Studio 3 in .gitignore file.
|
||||
.idea/caches
|
||||
.idea/modules.xml
|
||||
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
|
||||
.idea/navEditor.xml
|
||||
|
||||
# Keystore files
|
||||
# Uncomment the following lines if you do not want to check your keystore files in.
|
||||
#*.jks
|
||||
#*.keystore
|
||||
|
||||
# External native build folder generated in Android Studio 2.2 and later
|
||||
.externalNativeBuild
|
||||
.cxx/
|
||||
|
||||
# Google Services (e.g. APIs or Firebase)
|
||||
# google-services.json
|
||||
|
||||
# Freeline
|
||||
freeline.py
|
||||
freeline/
|
||||
freeline_project_description.json
|
||||
|
||||
# fastlane
|
||||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
||||
fastlane/test_output
|
||||
fastlane/readme.md
|
||||
|
||||
# Version control
|
||||
vcs.xml
|
||||
|
||||
# lint
|
||||
lint/intermediates/
|
||||
lint/generated/
|
||||
lint/outputs/
|
||||
lint/tmp/
|
||||
# lint/reports/
|
||||
|
||||
# Android Profiling
|
||||
*.hprof
|
||||
|
||||
# Cordova plugins for Capacitor
|
||||
capacitor-cordova-android-plugins
|
||||
|
||||
# Copied web assets
|
||||
app/src/main/assets/public
|
||||
|
||||
# Generated Config files
|
||||
app/src/main/assets/capacitor.config.json
|
||||
app/src/main/assets/capacitor.plugins.json
|
||||
app/src/main/res/xml/config.xml
|
2
android/app/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
/build/*
|
||||
!/build/.npmkeep
|
@ -1,54 +0,0 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace "com.example.app"
|
||||
compileSdk rootProject.ext.compileSdkVersion
|
||||
defaultConfig {
|
||||
applicationId "com.example.app"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
// Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61
|
||||
ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
flatDir{
|
||||
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
|
||||
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
|
||||
implementation project(':capacitor-android')
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
||||
implementation project(':capacitor-cordova-android-plugins')
|
||||
}
|
||||
|
||||
apply from: 'capacitor.build.gradle'
|
||||
|
||||
try {
|
||||
def servicesJSON = file('google-services.json')
|
||||
if (servicesJSON.text) {
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
}
|
||||
} catch(Exception e) {
|
||||
logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
|
||||
|
||||
android {
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
|
||||
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
|
||||
dependencies {
|
||||
implementation project(':capacitor-browser')
|
||||
implementation project(':capacitor-filesystem')
|
||||
implementation project(':capacitor-local-notifications')
|
||||
implementation project(':evva-capacitor-secure-storage-plugin')
|
||||
implementation project(':transistorsoft-capacitor-background-fetch')
|
||||
implementation "androidx.webkit:webkit:1.4.0"
|
||||
}
|
||||
|
||||
|
||||
if (hasProperty('postBuildExtras')) {
|
||||
postBuildExtras()
|
||||
}
|
21
android/app/proguard-rules.pro
vendored
@ -1,21 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
@ -1,26 +0,0 @@
|
||||
package com.getcapacitor.myapp;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
|
||||
@Test
|
||||
public void useAppContext() throws Exception {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
|
||||
assertEquals("com.getcapacitor.app", appContext.getPackageName());
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:usesCleartextTraffic="true">
|
||||
<activity
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/title_activity_main"
|
||||
android:theme="@style/AppTheme.NoActionBarLaunch"
|
||||
android:launchMode="singleTask"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths"></meta-data>
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
<!-- Permissions -->
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
||||
</manifest>
|
@ -1,31 +0,0 @@
|
||||
package com.example.app;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.transistorsoft.tsbackgroundfetch.BackgroundFetch;
|
||||
import com.transistorsoft.tsbackgroundfetch.BGTask;
|
||||
|
||||
public class BackgroundFetchHeadlessTask{
|
||||
public void onFetch(Context context, BGTask task) {
|
||||
// Get a reference to the BackgroundFetch Android API.
|
||||
BackgroundFetch backgroundFetch = BackgroundFetch.getInstance(context);
|
||||
// Get the taskId.
|
||||
String taskId = task.getTaskId();
|
||||
// Log a message to adb logcat.
|
||||
Log.d("MyHeadlessTask", "BackgroundFetchHeadlessTask onFetch -- CUSTOM IMPLEMENTATION: " + taskId);
|
||||
|
||||
boolean isTimeout = task.getTimedOut();
|
||||
// Is this a timeout?
|
||||
if (isTimeout) {
|
||||
backgroundFetch.finish(taskId);
|
||||
return;
|
||||
}
|
||||
// Do your work here...
|
||||
//
|
||||
//
|
||||
// Signal finish just like the Javascript API.
|
||||
backgroundFetch.finish(taskId);
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.example.app;
|
||||
|
||||
import com.getcapacitor.BridgeActivity;
|
||||
|
||||
public class MainActivity extends BridgeActivity {}
|
Before Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 17 KiB |
@ -1,34 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="78.5885"
|
||||
android:endY="90.9159"
|
||||
android:startX="48.7653"
|
||||
android:startY="61.0927"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1" />
|
||||
</vector>
|
@ -1,170 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path
|
||||
android:fillColor="#26A69A"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
</vector>
|
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 160 KiB |
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<WebView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_adaptive_back"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_adaptive_fore"/>
|
||||
</adaptive-icon>
|
Before Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 34 KiB |
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#FFFFFF</color>
|
||||
</resources>
|
@ -1,7 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<resources>
|
||||
<string name="app_name">Qortal </string>
|
||||
<string name="title_activity_main">Qortal </string>
|
||||
<string name="package_name">com.example.app</string>
|
||||
<string name="custom_url_scheme">com.example.app</string>
|
||||
</resources>
|
@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="android:background">@null</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="AppTheme.NoActionBarLaunch" parent="Theme.SplashScreen">
|
||||
<item name="android:background">@drawable/splash</item>
|
||||
</style>
|
||||
</resources>
|
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<external-path name="my_images" path="." />
|
||||
<cache-path name="my_cache_images" path="." />
|
||||
</paths>
|
@ -1,18 +0,0 @@
|
||||
package com.getcapacitor.myapp;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
|
||||
@Test
|
||||
public void addition_isCorrect() throws Exception {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.2.1'
|
||||
classpath 'com.google.gms:google-services:4.4.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
apply from: "variables.gradle"
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven {
|
||||
// capacitor-background-fetch
|
||||
url("${project(':transistorsoft-capacitor-background-fetch').projectDir}/libs")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
|
||||
include ':capacitor-android'
|
||||
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
|
||||
|
||||
include ':capacitor-browser'
|
||||
project(':capacitor-browser').projectDir = new File('../node_modules/@capacitor/browser/android')
|
||||
|
||||
include ':capacitor-filesystem'
|
||||
project(':capacitor-filesystem').projectDir = new File('../node_modules/@capacitor/filesystem/android')
|
||||
|
||||
include ':capacitor-local-notifications'
|
||||
project(':capacitor-local-notifications').projectDir = new File('../node_modules/@capacitor/local-notifications/android')
|
||||
|
||||
include ':evva-capacitor-secure-storage-plugin'
|
||||
project(':evva-capacitor-secure-storage-plugin').projectDir = new File('../node_modules/@evva/capacitor-secure-storage-plugin/android')
|
||||
|
||||
include ':transistorsoft-capacitor-background-fetch'
|
||||
project(':transistorsoft-capacitor-background-fetch').projectDir = new File('../node_modules/@transistorsoft/capacitor-background-fetch/android')
|
@ -1,22 +0,0 @@
|
||||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app's APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
@ -1,7 +0,0 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
248
android/gradlew
vendored
@ -1,248 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
92
android/gradlew.bat
vendored
@ -1,92 +0,0 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
@ -1,5 +0,0 @@
|
||||
include ':app'
|
||||
include ':capacitor-cordova-android-plugins'
|
||||
project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/')
|
||||
|
||||
apply from: 'capacitor.settings.gradle'
|
@ -1,16 +0,0 @@
|
||||
ext {
|
||||
minSdkVersion = 22
|
||||
compileSdkVersion = 34
|
||||
targetSdkVersion = 34
|
||||
androidxActivityVersion = '1.8.0'
|
||||
androidxAppCompatVersion = '1.6.1'
|
||||
androidxCoordinatorLayoutVersion = '1.2.0'
|
||||
androidxCoreVersion = '1.12.0'
|
||||
androidxFragmentVersion = '1.6.2'
|
||||
coreSplashScreenVersion = '1.0.1'
|
||||
androidxWebkitVersion = '1.9.0'
|
||||
junitVersion = '4.13.2'
|
||||
androidxJunitVersion = '1.1.5'
|
||||
androidxEspressoCoreVersion = '3.5.1'
|
||||
cordovaAndroidVersion = '10.1.1'
|
||||
}
|
@ -1,15 +1,15 @@
|
||||
import type { CapacitorConfig } from '@capacitor/cli';
|
||||
import type { CapacitorConfig } from "@capacitor/cli";
|
||||
|
||||
const config: CapacitorConfig = {
|
||||
appId: 'org.Qortal.Qortal-Hub',
|
||||
appName: 'Qortal-Hub',
|
||||
webDir: 'dist',
|
||||
"plugins": {
|
||||
"LocalNotifications": {
|
||||
"smallIcon": "qort",
|
||||
"iconColor": "#09b6e8"
|
||||
}
|
||||
}
|
||||
appId: "org.Qortal.Qortal-Hub",
|
||||
appName: "Qortal-Hub",
|
||||
webDir: "dist",
|
||||
plugins: {
|
||||
LocalNotifications: {
|
||||
smallIcon: "qort",
|
||||
iconColor: "#09b6e8",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
84
docs/contribution.md
Normal file
@ -0,0 +1,84 @@
|
||||
|
||||
# 🤝 Contributing Guide
|
||||
|
||||
Thank you for your interest in contributing! We follow a structured Git workflow to keep the project clean, stable, and production-ready at all times.
|
||||
|
||||
---
|
||||
|
||||
## 📦 Branch Overview
|
||||
|
||||
| Branch | Purpose |
|
||||
|------------------|----------------------------------------------------------|
|
||||
| `master` | Stable, production-ready code. All releases are tagged from here. |
|
||||
| `develop` | Active development branch. All new features go here first. |
|
||||
| `release/x.y.z` | Pre-release branch for staging, QA, and final polish. |
|
||||
|
||||
---
|
||||
|
||||
## 🌿 Creating a Feature or Fix
|
||||
|
||||
1. **Start from `develop`:**
|
||||
|
||||
```bash
|
||||
git checkout develop
|
||||
git checkout -b feature/your-feature-name
|
||||
```
|
||||
|
||||
2. **Make your changes and commit them.**
|
||||
|
||||
3. **Push your branch:**
|
||||
|
||||
```bash
|
||||
git push origin feature/your-feature-name
|
||||
```
|
||||
|
||||
4. **Open a Pull Request into `develop`.**
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Releasing Code (Maintainers Only)
|
||||
|
||||
A new `release/x.y.z` branch must be created for **every release**.
|
||||
|
||||
1. **Create a `release/` branch from `master`:**
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
git checkout -b release/1.2.0
|
||||
```
|
||||
|
||||
2. **Merge in `develop` or selected branches if `develop` is not ready:**
|
||||
|
||||
```bash
|
||||
git merge develop
|
||||
# or
|
||||
git merge feature/finished-feature
|
||||
git merge feature/another-complete-feature
|
||||
```
|
||||
|
||||
3. **Polish, test, and fix issues as needed.**
|
||||
|
||||
4. **Merge back into `develop`:**
|
||||
|
||||
```bash
|
||||
git checkout develop
|
||||
git merge release/1.2.0
|
||||
git push origin develop
|
||||
```
|
||||
|
||||
5. **Finalize the release:**
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
git merge release/1.2.0
|
||||
git tag v1.2.0
|
||||
git push origin master --tags
|
||||
```
|
||||
|
||||
6. **Delete the release branch:**
|
||||
|
||||
```bash
|
||||
git branch -d release/1.2.0
|
||||
git push origin --delete release/1.2.0
|
||||
```
|
||||
|
10
docs/i18n_languages.md
Normal file
@ -0,0 +1,10 @@
|
||||
# I18N Guidelines
|
||||
|
||||
In JSON file:
|
||||
|
||||
- Keep the file sorted
|
||||
- Always write in lowercase
|
||||
|
||||
In GUI:
|
||||
|
||||
- If the first letter of the translation must be uppercase, use the postProcess, for example: `{t_auth('advanced_users', { postProcess: 'capitalize' })}`
|
@ -1,15 +1,15 @@
|
||||
import type { CapacitorConfig } from '@capacitor/cli';
|
||||
import type { CapacitorConfig } from "@capacitor/cli";
|
||||
|
||||
const config: CapacitorConfig = {
|
||||
appId: 'org.Qortal.Qortal-Hub',
|
||||
appName: 'Qortal-Hub',
|
||||
webDir: 'dist',
|
||||
"plugins": {
|
||||
"LocalNotifications": {
|
||||
"smallIcon": "qort",
|
||||
"iconColor": "#09b6e8"
|
||||
}
|
||||
}
|
||||
appId: "org.Qortal.Qortal-Hub",
|
||||
appName: "Qortal-Hub",
|
||||
webDir: "dist",
|
||||
plugins: {
|
||||
LocalNotifications: {
|
||||
smallIcon: "qort",
|
||||
iconColor: "#09b6e8",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "qortal-hub",
|
||||
"version": "0.5.3",
|
||||
"version": "0.5.4-pre",
|
||||
"description": "A desktop app that gives you access to the Qortal network",
|
||||
"author": {
|
||||
"name": "",
|
||||
@ -57,4 +57,4 @@
|
||||
"capacitor",
|
||||
"electron"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
58
i18n.js
Normal file
@ -0,0 +1,58 @@
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
import HttpBackend from 'i18next-http-backend';
|
||||
import LocalStorageBackend from 'i18next-localstorage-backend';
|
||||
import HttpApi from 'i18next-http-backend';
|
||||
import i18n from 'i18next';
|
||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||
|
||||
// Detect environment
|
||||
const isDev = process.env.NODE_ENV === 'development';
|
||||
|
||||
// Register custom postProcessor: it capitalizes the first letter of a translation-
|
||||
// Usage:
|
||||
// t('greeting', { postProcess: 'capitalize' })
|
||||
const capitalize = {
|
||||
type: 'postProcessor',
|
||||
name: 'capitalize',
|
||||
process: (value) => {
|
||||
return value.charAt(0).toUpperCase() + value.slice(1);
|
||||
},
|
||||
};
|
||||
|
||||
export const supportedLanguages = {
|
||||
de: { name: 'Deutsch', flag: '🇩🇪' },
|
||||
en: { name: 'English', flag: '🇺🇸' },
|
||||
es: { name: 'Español', flag: '🇪🇸' },
|
||||
fr: { name: 'Français', flag: '🇫🇷' },
|
||||
it: { name: 'Italiano', flag: '🇮🇹' },
|
||||
ru: { name: 'Русский', flag: '🇷🇺' },
|
||||
};
|
||||
|
||||
i18n
|
||||
.use(HttpApi)
|
||||
.use(LanguageDetector)
|
||||
.use(initReactI18next)
|
||||
.use(capitalize)
|
||||
.init({
|
||||
backend: {
|
||||
backends: [LocalStorageBackend, HttpBackend],
|
||||
backendOptions: [
|
||||
{
|
||||
expirationTime: 7 * 24 * 60 * 60 * 1000, // 7 days
|
||||
},
|
||||
{
|
||||
loadPath: '/locales/{{lng}}/{{ns}}.json',
|
||||
},
|
||||
],
|
||||
},
|
||||
debug: isDev,
|
||||
fallbackLng: 'en',
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
lng: navigator.language,
|
||||
ns: ['auth', 'core', 'group', 'tutorial'],
|
||||
supportedLngs: Object.keys(supportedLanguages),
|
||||
});
|
||||
|
||||
export default i18n;
|
@ -1,12 +1,9 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
|
||||
<title>Qortal Hub</title>
|
||||
</head>
|
||||
<body>
|
||||
|
2164
package-lock.json
generated
79
package.json
@ -6,6 +6,7 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"format": "prettier --write .",
|
||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"preview": "vite preview",
|
||||
"test": "vitest",
|
||||
@ -19,32 +20,31 @@
|
||||
"@capacitor/core": "^6.1.2",
|
||||
"@capacitor/filesystem": "^6.0.1",
|
||||
"@capacitor/local-notifications": "^6.1.0",
|
||||
"@chatscope/chat-ui-kit-react": "^2.0.3",
|
||||
"@dnd-kit/core": "^6.1.0",
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"@dnd-kit/core": "^6.3.0",
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@electron/packager": "^18.3.6",
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@evva/capacitor-secure-storage-plugin": "^3.0.1",
|
||||
"@mui/icons-material": "^5.16.4",
|
||||
"@mui/lab": "^5.0.0-alpha.173",
|
||||
"@mui/material": "^5.16.7",
|
||||
"@reduxjs/toolkit": "^2.2.7",
|
||||
"@tanstack/react-virtual": "^3.10.8",
|
||||
"@mui/icons-material": "^7.0.1",
|
||||
"@mui/lab": "^7.0.0-beta.11",
|
||||
"@mui/material": "^7.0.1",
|
||||
"@tanstack/react-virtual": "^3.13.6",
|
||||
"@testing-library/jest-dom": "^6.4.6",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
"@tiptap/extension-color": "^2.5.9",
|
||||
"@tiptap/extension-highlight": "^2.6.6",
|
||||
"@tiptap/extension-image": "^2.6.6",
|
||||
"@tiptap/extension-mention": "^2.9.1",
|
||||
"@tiptap/extension-placeholder": "^2.6.2",
|
||||
"@tiptap/extension-text-style": "^2.5.9",
|
||||
"@tiptap/extension-underline": "^2.6.6",
|
||||
"@tiptap/pm": "^2.5.9",
|
||||
"@tiptap/react": "^2.5.9",
|
||||
"@tiptap/starter-kit": "^2.5.9",
|
||||
"@testing-library/user-event": "^14.6.1",
|
||||
"@tiptap/extension-color": "^2.11.7",
|
||||
"@tiptap/extension-highlight": "^2.11.7",
|
||||
"@tiptap/extension-image": "^2.11.7",
|
||||
"@tiptap/extension-mention": "^2.11.7",
|
||||
"@tiptap/extension-placeholder": "^2.11.7",
|
||||
"@tiptap/extension-text-style": "^2.11.7",
|
||||
"@tiptap/extension-underline": "^2.11.7",
|
||||
"@tiptap/pm": "^2.11.7",
|
||||
"@tiptap/react": "^2.11.7",
|
||||
"@tiptap/starter-kit": "^2.11.7",
|
||||
"@transistorsoft/capacitor-background-fetch": "^6.0.1",
|
||||
"@types/chrome": "^0.0.263",
|
||||
"@uiw/react-color": "^2.5.1",
|
||||
"adm-zip": "^0.5.16",
|
||||
"asmcrypto.js": "2.3.2",
|
||||
"axios": "^1.7.7",
|
||||
@ -60,29 +60,29 @@
|
||||
"emoji-picker-react": "^4.12.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"html-to-text": "^9.0.5",
|
||||
"i18next": "^25.0.1",
|
||||
"i18next-browser-languagedetector": "^8.0.5",
|
||||
"i18next-http-backend": "^3.0.2",
|
||||
"i18next-localstorage-backend": "^4.2.0",
|
||||
"jotai": "^2.12.3",
|
||||
"jssha": "3.3.1",
|
||||
"lit": "^3.2.1",
|
||||
"lodash": "^4.17.21",
|
||||
"mime": "^4.0.4",
|
||||
"moment": "^2.30.1",
|
||||
"npm": "^10.8.3",
|
||||
"quill-image-resize-module-react": "^3.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-copy-to-clipboard": "^5.1.0",
|
||||
"react": "^19.1.0",
|
||||
"react-countdown-circle-timer": "^3.2.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-dropzone": "^14.2.3",
|
||||
"react-frame-component": "^5.2.7",
|
||||
"react-infinite-scroller": "^1.2.6",
|
||||
"react-intersection-observer": "^9.13.0",
|
||||
"react-json-view-lite": "^2.0.1",
|
||||
"react-i18next": "^15.4.1",
|
||||
"react-intersection-observer": "^9.16.0",
|
||||
"react-json-view-lite": "^2.4.1",
|
||||
"react-loader-spinner": "^6.1.6",
|
||||
"react-qr-code": "^2.0.15",
|
||||
"react-quill": "^2.0.0",
|
||||
"react-redux": "^9.1.2",
|
||||
"react-virtualized": "^9.22.5",
|
||||
"react-virtualized": "^9.22.6",
|
||||
"react-virtuoso": "^4.10.4",
|
||||
"recoil": "^0.7.7",
|
||||
"short-unique-id": "^5.2.0",
|
||||
"slate": "^0.103.0",
|
||||
"slate-react": "^0.109.0",
|
||||
@ -94,14 +94,12 @@
|
||||
"vite-plugin-wasm": "^3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/dom": "^10.3.0",
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@types/dompurify": "^3.0.5",
|
||||
"@types/lodash": "^4.17.7",
|
||||
"@types/react": "^18.2.64",
|
||||
"@types/react-copy-to-clipboard": "^5.0.7",
|
||||
"@types/react-dom": "^18.2.21",
|
||||
"@types/react-infinite-scroller": "^1.2.5",
|
||||
"@types/react": "^19.1.0",
|
||||
"@types/react-dom": "^19.1.0",
|
||||
"@types/react-virtualized": "^9.21.30",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
||||
"@typescript-eslint/parser": "^7.1.1",
|
||||
@ -110,9 +108,16 @@
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.5",
|
||||
"prettier": "^3.5.3",
|
||||
"rename-cli": "^6.2.1",
|
||||
"typescript": "^5.2.2",
|
||||
"vite": "^5.1.6",
|
||||
"vitest": "^1.6.0"
|
||||
"vitest": "^1.6.1"
|
||||
},
|
||||
"overrides": {
|
||||
"react-loader-spinner": {
|
||||
"react": "^18 || ^19",
|
||||
"react-dom": "^18 || ^19"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
43
public/locales/de/auth.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"account": {
|
||||
"your": "ihr Konto",
|
||||
"account_many": "Konten",
|
||||
"account_one": "Konto"
|
||||
},
|
||||
"advanced_users": "für fortgeschrittene Benutzer",
|
||||
"apikey": {
|
||||
"alternative": "Alternative: Datei auswählen",
|
||||
"change": "API-Schlüssel ändern",
|
||||
"enter": "API-Schlüssel eingeben",
|
||||
"import": "API-Schlüssel importieren",
|
||||
"key": "API-Schlüssel",
|
||||
"select_valid": "gültigen API-Schlüssel auswählen"
|
||||
},
|
||||
"authenticate": "authentifizieren",
|
||||
"build_version": "Build-Version",
|
||||
"create_account": "Konto erstellen",
|
||||
"download_account": "Konto herunterladen",
|
||||
"keep_secure": "Bewahren Sie Ihre Kontodatei sicher auf",
|
||||
"node": {
|
||||
"choose": "benutzerdefinierten Node auswählen",
|
||||
"custom_many": "benutzerdefinierte Nodes",
|
||||
"use_custom": "benutzerdefinierten Node verwenden",
|
||||
"use_local": "lokalen Node verwenden",
|
||||
"using": "verwende Node",
|
||||
"using_public": "öffentlichen Node verwenden"
|
||||
},
|
||||
"password": "Passwort",
|
||||
"password_confirmation": "Passwort bestätigen",
|
||||
"return_to_list": "zurück zur Liste",
|
||||
"wallet": {
|
||||
"password_confirmation": "Wallet-Passwort bestätigen",
|
||||
"password": "Wallet-Passwort",
|
||||
"keep_password": "aktuelles Passwort beibehalten",
|
||||
"new_password": "neues Passwort",
|
||||
"error": {
|
||||
"missing_new_password": "bitte neues Passwort eingeben",
|
||||
"missing_password": "bitte Passwort eingeben"
|
||||
}
|
||||
},
|
||||
"welcome": "willkommen bei"
|
||||
}
|
71
public/locales/de/core.json
Normal file
@ -0,0 +1,71 @@
|
||||
{
|
||||
"add": "hinzufügen",
|
||||
"cancel": "abbrechen",
|
||||
"choose": "auswählen",
|
||||
"close": "schließen",
|
||||
"continue": "fortfahren",
|
||||
"core": {
|
||||
"block_height": "Blockhöhe",
|
||||
"information": "Kerninformationen",
|
||||
"peers": "verbundene Peers",
|
||||
"version": "Kernversion"
|
||||
},
|
||||
"description": "Beschreibung",
|
||||
"edit": "bearbeiten",
|
||||
"export": "exportieren",
|
||||
"import": "importieren",
|
||||
"last_height": "letzte Höhe",
|
||||
"loading": "Lade...",
|
||||
"logout": "abmelden",
|
||||
"minting_status": "Präge-Status",
|
||||
"payment_notification": "Zahlungsbenachrichtigung",
|
||||
"price": "Preis",
|
||||
"q_mail": "Q-Mail",
|
||||
"result": {
|
||||
"error": {
|
||||
"generic": "Ein Fehler ist aufgetreten",
|
||||
"incorrect_password": "Falsches Passwort",
|
||||
"save_qdn": "Speichern in QDN nicht möglich"
|
||||
},
|
||||
"status": {
|
||||
"minting": "(Prägung)",
|
||||
"not_minting": "(keine Prägung)",
|
||||
"synchronized": "synchronisiert",
|
||||
"synchronizing": "synchronisiere"
|
||||
},
|
||||
"success": {
|
||||
"publish_qdn": "Erfolgreich in QDN veröffentlicht"
|
||||
}
|
||||
},
|
||||
"save_options": {
|
||||
"no_pinned_changes": "Derzeit keine Änderungen an Ihren angehefteten Apps",
|
||||
"overwrite_changes": "Die App konnte Ihre vorhandenen in QDN gespeicherten angehefteten Apps nicht herunterladen. Möchten Sie diese Änderungen überschreiben?",
|
||||
"overwrite_qdn": "In QDN überschreiben",
|
||||
"publish_qdn": "Möchten Sie Ihre Einstellungen in QDN (verschlüsselt) veröffentlichen?",
|
||||
"qdn": "QDN-Speicherung verwenden",
|
||||
"register_name": "Sie benötigen einen registrierten Qortal-Namen, um Ihre angehefteten Apps in QDN zu speichern.",
|
||||
"reset_pinned": "Gefällt Ihnen Ihre aktuellen lokalen Änderungen nicht? Möchten Sie zu den Standard-Anheftungen zurückkehren?",
|
||||
"reset_qdn": "Gefällt Ihnen Ihre aktuellen lokalen Änderungen nicht? Möchten Sie zu Ihren in QDN gespeicherten Anheftungen zurückkehren?",
|
||||
"revert_default": "Auf Standard zurücksetzen",
|
||||
"revert_qdn": "Auf QDN zurücksetzen",
|
||||
"save_qdn": "In QDN speichern",
|
||||
"save": "speichern",
|
||||
"settings": "Sie verwenden die Export/Import-Methode zum Speichern von Einstellungen.",
|
||||
"unsaved_changes": "Sie haben nicht gespeicherte Änderungen an Ihren angehefteten Apps. Speichern Sie sie in QDN."
|
||||
},
|
||||
"settings": "Einstellungen",
|
||||
"supply": "Angebot",
|
||||
"theme": {
|
||||
"dark": "Dunkelmodus",
|
||||
"light": "Hellmodus"
|
||||
},
|
||||
"title": "Titel",
|
||||
"tutorial": "Tutorial",
|
||||
"user_lookup": "Benutzersuche",
|
||||
"wallet": {
|
||||
"backup_wallet": "Wallet sichern",
|
||||
"wallet": "Wallet",
|
||||
"wallet_other": "Wallets"
|
||||
},
|
||||
"welcome": "Willkommen"
|
||||
}
|
21
public/locales/de/tutorial.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"1_getting_started": "1. Erste Schritte",
|
||||
"2_overview": "2. Überblick",
|
||||
"3_groups": "3. Qortal-Gruppen",
|
||||
"4_obtain_qort": "4. QORT erhalten",
|
||||
"account_creation": "Kontoerstellung",
|
||||
"important_info": "wichtige Informationen!",
|
||||
"apps": {
|
||||
"dashboard": "1. App-Dashboard",
|
||||
"navigation": "2. App-Navigation"
|
||||
},
|
||||
"initial": {
|
||||
"6_qort": "mindestens 6 QORT im Wallet haben",
|
||||
"explore": "erkunden",
|
||||
"general_chat": "allgemeiner Chat",
|
||||
"getting_started": "erste Schritte",
|
||||
"register_name": "einen Namen registrieren",
|
||||
"see_apps": "apps ansehen",
|
||||
"trade_qort": "QORT handeln"
|
||||
}
|
||||
}
|
48
public/locales/en/auth.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"account": {
|
||||
"your": "your account",
|
||||
"account_many": "accounts",
|
||||
"account_one": "account"
|
||||
},
|
||||
"advanced_users": "for advanced users",
|
||||
"apikey": {
|
||||
"alternative": "alternative: File select",
|
||||
"change": "change APIkey",
|
||||
"enter": "enter APIkey",
|
||||
"import": "import APIkey",
|
||||
"key": "API key",
|
||||
"select_valid": "select a valid apikey"
|
||||
},
|
||||
"authenticate": "authenticate",
|
||||
"build_version": "build version",
|
||||
"create_account": "create account",
|
||||
"download_account": "download account",
|
||||
"keep_secure": "keep your account file secure",
|
||||
"node": {
|
||||
"choose": "choose custom node",
|
||||
"custom_many": "custom nodes",
|
||||
"use_custom": "use custom node",
|
||||
"use_local": "use local node",
|
||||
"using": "using node",
|
||||
"using_public": "using public node"
|
||||
},
|
||||
"password": "password",
|
||||
"password_confirmation": "confirm password",
|
||||
"return_to_list": "return to list",
|
||||
"tips": {
|
||||
"digital_id": "your wallet is like your digital ID on Qortal, and is how you will login to the Qortal User Interface. It holds your public address and the Qortal name you will eventually choose. Every transaction you make is linked to your ID, and this is where you manage all your QORT and other tradeable cryptocurrencies on Qortal.",
|
||||
"new_account": "creating an account means creating a new wallet and digital ID to start using Qortal. Once you have made your account, you can start doing things like obtaining some QORT, buying a name and avatar, publishing videos and blogs, and much more.",
|
||||
"new_users": "new users start here!"
|
||||
},
|
||||
"wallet": {
|
||||
"password_confirmation": "confirm wallet password",
|
||||
"password": "wallet password",
|
||||
"keep_password": "keep current password",
|
||||
"new_password": "new password",
|
||||
"error": {
|
||||
"missing_new_password": "please enter a new password",
|
||||
"missing_password": "please enter your password"
|
||||
}
|
||||
},
|
||||
"welcome": "welcome to"
|
||||
}
|
111
public/locales/en/core.json
Normal file
@ -0,0 +1,111 @@
|
||||
{
|
||||
"action": {
|
||||
"add": "add",
|
||||
"accept": "accept",
|
||||
"backup_account": "backup account",
|
||||
"backup_wallet": "backup wallet",
|
||||
"cancel": "cancel",
|
||||
"change": "change",
|
||||
"change_language": "change language",
|
||||
"choose": "choose",
|
||||
"close": "close",
|
||||
"continue": "continue",
|
||||
"continue_logout": "continue to logout",
|
||||
"decline": "decline",
|
||||
"edit": "edit",
|
||||
"export": "export",
|
||||
"import": "import",
|
||||
"invite": "invite",
|
||||
"join": "join",
|
||||
"logout": "logout",
|
||||
"notify": "notify"
|
||||
},
|
||||
"core": {
|
||||
"block_height": "block height",
|
||||
"information": "core information",
|
||||
"peers": "connected peers",
|
||||
"version": "core version"
|
||||
},
|
||||
"count": {
|
||||
"none": "none",
|
||||
"one": "one"
|
||||
},
|
||||
"description": "description",
|
||||
"fee": {
|
||||
"payment": "payment fee",
|
||||
"publish": "publish fee"
|
||||
},
|
||||
"page": {
|
||||
"last": "last",
|
||||
"first": "first",
|
||||
"next": "next",
|
||||
"previous": "previous"
|
||||
},
|
||||
"downloading_qdn": "downloading from QDN",
|
||||
"last_height": "last height",
|
||||
"loading": "loading...",
|
||||
"loading_posts": "loading posts... please wait.",
|
||||
"message_us": "please message us on Telegram or Discord if you need 4 QORT to start chatting without any limitations",
|
||||
"minting_status": "minting status",
|
||||
"new_user": "are you a new user?",
|
||||
"payment_notification": "payment notification",
|
||||
"price": "price",
|
||||
"q_mail": "q-mail",
|
||||
"message": {
|
||||
"error": {
|
||||
"generic": "an error occurred",
|
||||
"incorrect_password": "incorrect password",
|
||||
"save_qdn": "unable to save to QDN"
|
||||
},
|
||||
"status": {
|
||||
"minting": "(minting)",
|
||||
"not_minting": "(not minting)",
|
||||
"synchronized": "synchronized",
|
||||
"synchronizing": "synchronizing"
|
||||
},
|
||||
"success": {
|
||||
"order_submitted": "your buy order was submitted",
|
||||
"publish_qdn": "successfully published to QDN",
|
||||
"request_read": "I have read this request",
|
||||
"transfer": "the transfer was succesful!"
|
||||
}
|
||||
},
|
||||
"save_options": {
|
||||
"no_pinned_changes": "you currently do not have any changes to your pinned apps",
|
||||
"overwrite_changes": "the app was unable to download your existing QDN-saved pinned apps. Would you like to overwrite those changes?",
|
||||
"overwrite_qdn": "overwrite to QDN",
|
||||
"publish_qdn": "would you like to publish your settings to QDN (encrypted)?",
|
||||
"qdn": "use QDN saving",
|
||||
"register_name": "you need a registered Qortal name to save your pinned apps to QDN.",
|
||||
"reset_pinned": "don't like your current local changes? Would you like to reset to the default pinned apps?",
|
||||
"reset_qdn": "don't like your current local changes? Would you like to reset to your saved QDN pinned apps?",
|
||||
"revert_default": "revert to default",
|
||||
"revert_qdn": "revert to QDN",
|
||||
"save_qdn": "save to QDN",
|
||||
"save": "save",
|
||||
"settings": "you are using the export/import way of saving settings.",
|
||||
"unsaved_changes": " you have unsaved changes to your pinned apps. Save them to QDN."
|
||||
},
|
||||
"settings": "settings",
|
||||
"supply": "supply",
|
||||
"theme": {
|
||||
"dark": "dark mode",
|
||||
"light": "light mode"
|
||||
},
|
||||
"time": {
|
||||
"day_one": "{{count}} day",
|
||||
"day_other": "{{count}} days",
|
||||
"hour_one": "{{count}} hour",
|
||||
"hour_other": "{{count}} hours",
|
||||
"minute_one": "{{count}} minute",
|
||||
"minute_other": "{{count}} minutes"
|
||||
},
|
||||
"title": "title",
|
||||
"tutorial": "tutorial",
|
||||
"user_lookup": "user lookup",
|
||||
"wallet": {
|
||||
"wallet": "wallet",
|
||||
"wallet_other": "wallets"
|
||||
},
|
||||
"welcome": "welcome"
|
||||
}
|
65
public/locales/en/group.json
Normal file
@ -0,0 +1,65 @@
|
||||
{
|
||||
"action": {
|
||||
"cancel_ban": "cancel ban",
|
||||
"create_group": "create group",
|
||||
"find_group": "find group",
|
||||
"join_group": "join group",
|
||||
"invite_member": "invite member",
|
||||
"refetch_page": "refetch page",
|
||||
"return_to_thread": "return to threads"
|
||||
},
|
||||
"advanced_options": "advanced options",
|
||||
"approval_threshold": "group Approval Threshold (number / percentage of Admins that must approve a transaction)",
|
||||
"ban_list": "ban list",
|
||||
"block_delay": {
|
||||
"minimum": "minimum Block delay for Group Transaction Approvals",
|
||||
"maximum": "maximum Block delay for Group Transaction Approvals"
|
||||
},
|
||||
"group": {
|
||||
"closed": "closed (private) - users need permission to join",
|
||||
"description": "description of group",
|
||||
"invites": "group invites",
|
||||
"management": "group management",
|
||||
"name": "name of group",
|
||||
"open": "open (public)",
|
||||
"type": "group type"
|
||||
},
|
||||
"invitation_expiry": "invitation Expiry Time",
|
||||
"join_requests": "join requests",
|
||||
"question": {
|
||||
"cancel_ban": "would you like to perform a CANCEL_GROUP_BAN transaction?",
|
||||
"create_group": "would you like to perform an CREATE_GROUP transaction?",
|
||||
"group_invite": "would you like to perform a GROUP_INVITE transaction?",
|
||||
"join_group": "would you like to perform an JOIN_GROUP transaction?",
|
||||
"provide_thread": "please provide a thread title"
|
||||
},
|
||||
"message": {
|
||||
"generic": {
|
||||
"encryption_key": "the group's first common encryption key is in the process of creation. Please wait a few minutes for it to be retrieved by the network. Checking every 2 minutes...",
|
||||
"group_invited_you": "{{group}} has invited you",
|
||||
"no_display": "nothing to display",
|
||||
"no_selection": "no group selected",
|
||||
"not_part_group": "you are not part of the encrypted group of members. Wait until an admin re-encrypts the keys.",
|
||||
"only_encrypted": "only unencrypted messages will be displayed.",
|
||||
"setting_group": "setting up group... please wait."
|
||||
},
|
||||
"error": {
|
||||
"access_name": "cannot send a message without a access to your name",
|
||||
"description_required": "please provide a description",
|
||||
"group_info": "cannot access group information",
|
||||
"name_required": "please provide a name",
|
||||
"notify_admins": "try notifying an admin from the list of admins below:"
|
||||
},
|
||||
"success": {
|
||||
"group_creation": "successfully created group. It may take a couple of minutes for the changes to propagate",
|
||||
"group_creation_name": "created group {{group_name}}: awaiting confirmation",
|
||||
"group_creation_label": "created group {{name}}: success!",
|
||||
"group_invite": "successfully invited {{value}}. It may take a couple of minutes for the changes to propagate",
|
||||
"join_creation": "successfully requested to join group. It may take a couple of minutes for the changes to propagate",
|
||||
"group_join_name": "joined group {{group_name}}: awaiting confirmation",
|
||||
"group_join_label": "joined group {{name}}: success!",
|
||||
"loading_threads": "loading threads... please wait.",
|
||||
"unbanned_user": "successfully unbanned user. It may take a couple of minutes for the changes to propagate"
|
||||
}
|
||||
}
|
||||
}
|
21
public/locales/en/tutorial.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"1_getting_started": "1. Getting Started",
|
||||
"2_overview": "2. Overview",
|
||||
"3_groups": "3. Qortal Groups",
|
||||
"4_obtain_qort": "4. Obtaining Qort",
|
||||
"account_creation": "account creation",
|
||||
"important_info": "important information!",
|
||||
"apps": {
|
||||
"dashboard": "1. Apps Dashboard",
|
||||
"navigation": "2. Apps Navigation"
|
||||
},
|
||||
"initial": {
|
||||
"6_qort": "have at least 6 QORT in your wallet",
|
||||
"explore": "explore",
|
||||
"general_chat": "general chat",
|
||||
"getting_started": "getting started",
|
||||
"register_name": "register a name",
|
||||
"see_apps": "see apps",
|
||||
"trade_qort": "trade QORT"
|
||||
}
|
||||
}
|
43
public/locales/es/auth.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"account": {
|
||||
"your": "tu cuenta",
|
||||
"account_many": "cuentas",
|
||||
"account_one": "cuenta"
|
||||
},
|
||||
"advanced_users": "para usuarios avanzados",
|
||||
"apikey": {
|
||||
"alternative": "alternativa: Seleccionar archivo",
|
||||
"change": "cambiar clave API",
|
||||
"enter": "ingresar clave API",
|
||||
"import": "importar clave API",
|
||||
"key": "clave API",
|
||||
"select_valid": "selecciona una clave API válida"
|
||||
},
|
||||
"authenticate": "autenticar",
|
||||
"build_version": "versión de compilación",
|
||||
"create_account": "crear cuenta",
|
||||
"download_account": "descargar cuenta",
|
||||
"keep_secure": "mantén tu archivo de cuenta seguro",
|
||||
"node": {
|
||||
"choose": "elegir nodo personalizado",
|
||||
"custom_many": "nodos personalizados",
|
||||
"use_custom": "usar nodo personalizado",
|
||||
"use_local": "usar nodo local",
|
||||
"using": "usando nodo",
|
||||
"using_public": "usando nodo público"
|
||||
},
|
||||
"password": "contraseña",
|
||||
"password_confirmation": "confirmar contraseña",
|
||||
"return_to_list": "volver a la lista",
|
||||
"wallet": {
|
||||
"password_confirmation": "confirmar contraseña del monedero",
|
||||
"password": "contraseña del monedero",
|
||||
"keep_password": "mantener la contraseña actual",
|
||||
"new_password": "nueva contraseña",
|
||||
"error": {
|
||||
"missing_new_password": "por favor ingresa una nueva contraseña",
|
||||
"missing_password": "por favor ingresa tu contraseña"
|
||||
}
|
||||
},
|
||||
"welcome": "bienvenido a"
|
||||
}
|
71
public/locales/es/core.json
Normal file
@ -0,0 +1,71 @@
|
||||
{
|
||||
"add": "agregar",
|
||||
"cancel": "cancelar",
|
||||
"choose": "elegir",
|
||||
"close": "cerrar",
|
||||
"continue": "continuar",
|
||||
"core": {
|
||||
"block_height": "altura de bloque",
|
||||
"information": "información del núcleo",
|
||||
"peers": "pares conectados",
|
||||
"version": "versión del núcleo"
|
||||
},
|
||||
"description": "descripción",
|
||||
"edit": "editar",
|
||||
"export": "exportar",
|
||||
"import": "importar",
|
||||
"last_height": "última altura",
|
||||
"loading": "cargando...",
|
||||
"logout": "cerrar sesión",
|
||||
"minting_status": "estado de acuñación",
|
||||
"payment_notification": "notificación de pago",
|
||||
"price": "precio",
|
||||
"q_mail": "q-mail",
|
||||
"result": {
|
||||
"error": {
|
||||
"generic": "ocurrió un error",
|
||||
"incorrect_password": "contraseña incorrecta",
|
||||
"save_qdn": "no se pudo guardar en QDN"
|
||||
},
|
||||
"status": {
|
||||
"minting": "(acuñando)",
|
||||
"not_minting": "(no acuñando)",
|
||||
"synchronized": "sincronizado",
|
||||
"synchronizing": "sincronizando"
|
||||
},
|
||||
"success": {
|
||||
"publish_qdn": "publicado exitosamente en QDN"
|
||||
}
|
||||
},
|
||||
"save_options": {
|
||||
"no_pinned_changes": "actualmente no tienes cambios en tus aplicaciones fijadas",
|
||||
"overwrite_changes": "la aplicación no pudo descargar tus aplicaciones fijadas existentes guardadas en QDN. ¿Deseas sobrescribir esos cambios?",
|
||||
"overwrite_qdn": "sobrescribir en QDN",
|
||||
"publish_qdn": "¿Deseas publicar tus configuraciones en QDN (cifrado)?",
|
||||
"qdn": "usar guardado en QDN",
|
||||
"register_name": "necesitas un nombre Qortal registrado para guardar tus aplicaciones fijadas en QDN.",
|
||||
"reset_pinned": "¿No te gustan tus cambios locales actuales? ¿Deseas restablecer las aplicaciones fijadas predeterminadas?",
|
||||
"reset_qdn": "¿No te gustan tus cambios locales actuales? ¿Deseas restablecer tus aplicaciones fijadas guardadas en QDN?",
|
||||
"revert_default": "restablecer a predeterminado",
|
||||
"revert_qdn": "restablecer a QDN",
|
||||
"save_qdn": "guardar en QDN",
|
||||
"save": "guardar",
|
||||
"settings": "estás utilizando el método de exportación/importación para guardar configuraciones.",
|
||||
"unsaved_changes": "tienes cambios no guardados en tus aplicaciones fijadas. Guárdalos en QDN."
|
||||
},
|
||||
"settings": "configuraciones",
|
||||
"supply": "suministro",
|
||||
"theme": {
|
||||
"dark": "modo oscuro",
|
||||
"light": "modo claro"
|
||||
},
|
||||
"title": "título",
|
||||
"tutorial": "tutorial",
|
||||
"user_lookup": "búsqueda de usuario",
|
||||
"wallet": {
|
||||
"backup_wallet": "respaldar billetera",
|
||||
"wallet": "billetera",
|
||||
"wallet_other": "billeteras"
|
||||
},
|
||||
"welcome": "bienvenido"
|
||||
}
|
21
public/locales/es/tutorial.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"1_getting_started": "1. Comenzando",
|
||||
"2_overview": "2. Visión general",
|
||||
"3_groups": "3. Grupos de Qortal",
|
||||
"4_obtain_qort": "4. Obtener QORT",
|
||||
"account_creation": "creación de cuenta",
|
||||
"important_info": "¡información importante!",
|
||||
"apps": {
|
||||
"dashboard": "1. Panel de aplicaciones",
|
||||
"navigation": "2. Navegación de aplicaciones"
|
||||
},
|
||||
"initial": {
|
||||
"6_qort": "tener al menos 6 QORT en tu monedero",
|
||||
"explore": "explorar",
|
||||
"general_chat": "chat general",
|
||||
"getting_started": "comenzando",
|
||||
"register_name": "registrar un nombre",
|
||||
"see_apps": "ver aplicaciones",
|
||||
"trade_qort": "intercambiar QORT"
|
||||
}
|
||||
}
|
43
public/locales/fr/auth.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"account": {
|
||||
"your": "ton compte",
|
||||
"account_many": "comptes",
|
||||
"account_one": "compte"
|
||||
},
|
||||
"advanced_users": "pour les utilisateurs avancés",
|
||||
"apikey": {
|
||||
"alternative": "alternative : Sélectionner un fichier",
|
||||
"change": "changer la clé API",
|
||||
"enter": "entrer la clé API",
|
||||
"import": "importer la clé API",
|
||||
"key": "clé API",
|
||||
"select_valid": "sélectionnez une clé API valide"
|
||||
},
|
||||
"authenticate": "authentifier",
|
||||
"build_version": "version de build",
|
||||
"create_account": "créer un compte",
|
||||
"download_account": "télécharger le compte",
|
||||
"keep_secure": "Gardez votre fichier de compte en sécurité",
|
||||
"node": {
|
||||
"choose": "choisir un nœud personnalisé",
|
||||
"custom_many": "nœuds personnalisés",
|
||||
"use_custom": "utiliser un nœud personnalisé",
|
||||
"use_local": "utiliser un nœud local",
|
||||
"using": "utilise le nœud",
|
||||
"using_public": "utilise un nœud public"
|
||||
},
|
||||
"password": "mot de passe",
|
||||
"password_confirmation": "confirmer le mot de passe",
|
||||
"return_to_list": "retour à la liste",
|
||||
"wallet": {
|
||||
"password_confirmation": "confirmer le mot de passe du portefeuille",
|
||||
"password": "mot de passe du portefeuille",
|
||||
"keep_password": "garder le mot de passe actuel",
|
||||
"new_password": "nouveau mot de passe",
|
||||
"error": {
|
||||
"missing_new_password": "veuillez entrer un nouveau mot de passe",
|
||||
"missing_password": "veuillez entrer votre mot de passe"
|
||||
}
|
||||
},
|
||||
"welcome": "bienvenue sur"
|
||||
}
|
71
public/locales/fr/core.json
Normal file
@ -0,0 +1,71 @@
|
||||
{
|
||||
"add": "ajouter",
|
||||
"cancel": "annuler",
|
||||
"choose": "choisir",
|
||||
"close": "fermer",
|
||||
"continue": "continuer",
|
||||
"core": {
|
||||
"block_height": "hauteur de bloc",
|
||||
"information": "informations du noyau",
|
||||
"peers": "pairs connectés",
|
||||
"version": "version du noyau"
|
||||
},
|
||||
"description": "description",
|
||||
"edit": "éditer",
|
||||
"export": "exporter",
|
||||
"import": "importer",
|
||||
"last_height": "dernière hauteur",
|
||||
"loading": "chargement...",
|
||||
"logout": "se déconnecter",
|
||||
"minting_status": "statut de frappe",
|
||||
"payment_notification": "notification de paiement",
|
||||
"price": "prix",
|
||||
"q_mail": "q-mail",
|
||||
"result": {
|
||||
"error": {
|
||||
"generic": "une erreur s'est produite",
|
||||
"incorrect_password": "mot de passe incorrect",
|
||||
"save_qdn": "impossible d'enregistrer dans QDN"
|
||||
},
|
||||
"status": {
|
||||
"minting": "(frappe en cours)",
|
||||
"not_minting": "(pas de frappe)",
|
||||
"synchronized": "synchronisé",
|
||||
"synchronizing": "synchronisation en cours"
|
||||
},
|
||||
"success": {
|
||||
"publish_qdn": "publié avec succès dans QDN"
|
||||
}
|
||||
},
|
||||
"save_options": {
|
||||
"no_pinned_changes": "vous n'avez actuellement aucune modification de vos applications épinglées",
|
||||
"overwrite_changes": "l'application n'a pas pu télécharger vos applications épinglées existantes enregistrées dans QDN. Voulez-vous écraser ces modifications ?",
|
||||
"overwrite_qdn": "écraser dans QDN",
|
||||
"publish_qdn": "souhaitez-vous publier vos paramètres dans QDN (chiffré) ?",
|
||||
"qdn": "utiliser l'enregistrement QDN",
|
||||
"register_name": "vous devez avoir un nom Qortal enregistré pour enregistrer vos applications épinglées dans QDN.",
|
||||
"reset_pinned": "vous n'aimez pas vos modifications locales actuelles ? Voulez-vous réinitialiser les applications épinglées par défaut ?",
|
||||
"reset_qdn": "vous n'aimez pas vos modifications locales actuelles ? Voulez-vous réinitialiser vos applications épinglées enregistrées dans QDN ?",
|
||||
"revert_default": "revenir aux paramètres par défaut",
|
||||
"revert_qdn": "revenir à QDN",
|
||||
"save_qdn": "enregistrer dans QDN",
|
||||
"save": "enregistrer",
|
||||
"settings": "vous utilisez la méthode d'exportation/importation pour enregistrer les paramètres.",
|
||||
"unsaved_changes": "vous avez des modifications non enregistrées de vos applications épinglées. Enregistrez-les dans QDN."
|
||||
},
|
||||
"settings": "paramètres",
|
||||
"supply": "approvisionnement",
|
||||
"theme": {
|
||||
"dark": "mode sombre",
|
||||
"light": "mode clair"
|
||||
},
|
||||
"title": "titre",
|
||||
"tutorial": "tutoriel",
|
||||
"user_lookup": "recherche d'utilisateur",
|
||||
"wallet": {
|
||||
"backup_wallet": "sauvegarder le portefeuille",
|
||||
"wallet": "portefeuille",
|
||||
"wallet_other": "portefeuilles"
|
||||
},
|
||||
"welcome": "bienvenue"
|
||||
}
|
21
public/locales/fr/tutorial.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"1_getting_started": "1. Démarrer",
|
||||
"2_overview": "2. Aperçu",
|
||||
"3_groups": "3. Groupes Qortal",
|
||||
"4_obtain_qort": "4. Obtenir des QORT",
|
||||
"account_creation": "création de compte",
|
||||
"important_info": "informations importantes !",
|
||||
"apps": {
|
||||
"dashboard": "1. Tableau de bord des applications",
|
||||
"navigation": "2. Navigation des applications"
|
||||
},
|
||||
"initial": {
|
||||
"6_qort": "avoir au moins 6 QORT dans votre portefeuille",
|
||||
"explore": "explorer",
|
||||
"general_chat": "chat général",
|
||||
"getting_started": "démarrer",
|
||||
"register_name": "enregistrer un nom",
|
||||
"see_apps": "voir les applications",
|
||||
"trade_qort": "échanger des QORT"
|
||||
}
|
||||
}
|
48
public/locales/it/auth.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"account": {
|
||||
"your": "il tuo account",
|
||||
"account_many": "account",
|
||||
"account_one": "account"
|
||||
},
|
||||
"advanced_users": "per utenti avanzati",
|
||||
"apikey": {
|
||||
"alternative": "alternativa: selezione file",
|
||||
"change": "cambia APIkey",
|
||||
"enter": "inserisci APIkey",
|
||||
"import": "importa APIkey",
|
||||
"key": "chiave API",
|
||||
"select_valid": "seleziona una APIkey valida"
|
||||
},
|
||||
"authenticate": "autentica",
|
||||
"build_version": "versione build",
|
||||
"create_account": "crea account",
|
||||
"download_account": "scarica account",
|
||||
"keep_secure": "mantieni sicuro il file del tuo account",
|
||||
"node": {
|
||||
"choose": "scegli nodo personalizzato",
|
||||
"custom_many": "nodi personalizzati",
|
||||
"use_custom": "usa nodo personalizzato",
|
||||
"use_local": "usa nodo locale",
|
||||
"using": "utilizzo nodo",
|
||||
"using_public": "utilizzo nodo pubblico"
|
||||
},
|
||||
"password": "password",
|
||||
"password_confirmation": "conferma password",
|
||||
"return_to_list": "torna alla lista",
|
||||
"tips": {
|
||||
"digital_id": "il tuo wallet è come la tua identità digitale su Qortal ed è il modo in cui accederai all'interfaccia utente di Qortal. Contiene il tuo indirizzo pubblico e il nome Qortal che sceglierai. Ogni transazione che esegui è collegata alla tua identità ed è qui che gestisci tutti i tuoi QORT e altre criptovalute scambiabili su Qortal.",
|
||||
"new_account": "creare un account significa creare un nuovo wallet e un'identità digitale per iniziare a usare Qortal. Una volta creato l'account, potrai iniziare a ottenere QORT, acquistare un nome e un avatar, pubblicare video e blog, e molto altro.",
|
||||
"new_users": "i nuovi utenti iniziano qui!"
|
||||
},
|
||||
"wallet": {
|
||||
"password_confirmation": "conferma password del wallet",
|
||||
"password": "password del wallet",
|
||||
"keep_password": "mantieni password corrente",
|
||||
"new_password": "nuova password",
|
||||
"error": {
|
||||
"missing_new_password": "per favore inserisci una nuova password",
|
||||
"missing_password": "per favore inserisci la tua password"
|
||||
}
|
||||
},
|
||||
"welcome": "benvenuto in"
|
||||
}
|
111
public/locales/it/core.json
Normal file
@ -0,0 +1,111 @@
|
||||
{
|
||||
"action": {
|
||||
"add": "aggiungi",
|
||||
"accept": "accetta",
|
||||
"backup_account": "backup account",
|
||||
"backup_wallet": "backup wallet",
|
||||
"cancel": "annulla",
|
||||
"change": "cambia",
|
||||
"change_language": "cambia lingua",
|
||||
"choose": "scegli",
|
||||
"close": "chiudi",
|
||||
"continue": "continua",
|
||||
"continue_logout": "continua con il logout",
|
||||
"decline": "rifiuta",
|
||||
"edit": "modifica",
|
||||
"export": "esporta",
|
||||
"import": "importa",
|
||||
"invite": "invita",
|
||||
"join": "unisciti",
|
||||
"logout": "esci",
|
||||
"notify": "notifica"
|
||||
},
|
||||
"core": {
|
||||
"block_height": "altezza blocco",
|
||||
"information": "informazioni core",
|
||||
"peers": "peer connessi",
|
||||
"version": "versione core"
|
||||
},
|
||||
"count": {
|
||||
"none": "nessuno",
|
||||
"one": "uno"
|
||||
},
|
||||
"description": "descrizione",
|
||||
"fee": {
|
||||
"payment": "commissione di pagamento",
|
||||
"publish": "commissione di pubblicazione"
|
||||
},
|
||||
"page": {
|
||||
"last": "ultimo",
|
||||
"first": "primo",
|
||||
"next": "successivo",
|
||||
"previous": "precedente"
|
||||
},
|
||||
"downloading_qdn": "scaricamento da QDN",
|
||||
"last_height": "ultima altezza",
|
||||
"loading": "caricamento...",
|
||||
"loading_posts": "caricamento post... attendere prego.",
|
||||
"message_us": "per favore scrivici su Telegram o Discord se hai bisogno di 4 QORT per iniziare a chattare senza limitazioni",
|
||||
"minting_status": "stato minting",
|
||||
"new_user": "sei un nuovo utente?",
|
||||
"payment_notification": "notifica di pagamento",
|
||||
"price": "prezzo",
|
||||
"q_mail": "q-mail",
|
||||
"message": {
|
||||
"error": {
|
||||
"generic": "si è verificato un errore",
|
||||
"incorrect_password": "password errata",
|
||||
"save_qdn": "impossibile salvare su QDN"
|
||||
},
|
||||
"status": {
|
||||
"minting": "(minting)",
|
||||
"not_minting": "(non minting)",
|
||||
"synchronized": "sincronizzato",
|
||||
"synchronizing": "sincronizzazione in corso"
|
||||
},
|
||||
"success": {
|
||||
"order_submitted": "il tuo ordine di acquisto è stato inviato",
|
||||
"publish_qdn": "pubblicato su QDN con successo",
|
||||
"request_read": "ho letto questa richiesta",
|
||||
"transfer": "il trasferimento è stato effettuato con successo!"
|
||||
}
|
||||
},
|
||||
"save_options": {
|
||||
"no_pinned_changes": "attualmente non hai modifiche alle tue app appuntate",
|
||||
"overwrite_changes": "l'app non è riuscita a scaricare le tue app appuntate salvate su QDN. Vuoi sovrascrivere le modifiche?",
|
||||
"overwrite_qdn": "sovrascrivi su QDN",
|
||||
"publish_qdn": "vuoi pubblicare le tue impostazioni su QDN (crittografato)?",
|
||||
"qdn": "usa il salvataggio su QDN",
|
||||
"register_name": "devi avere un nome Qortal registrato per salvare le tue app appuntate su QDN.",
|
||||
"reset_pinned": "non ti piacciono le modifiche locali attuali? Vuoi ripristinare le app appuntate predefinite?",
|
||||
"reset_qdn": "non ti piacciono le modifiche locali attuali? Vuoi ripristinare le app appuntate salvate su QDN?",
|
||||
"revert_default": "ripristina predefinito",
|
||||
"revert_qdn": "ripristina da QDN",
|
||||
"save_qdn": "salva su QDN",
|
||||
"save": "salva",
|
||||
"settings": "stai usando il metodo di esportazione/importazione per salvare le impostazioni.",
|
||||
"unsaved_changes": "hai modifiche non salvate alle tue app appuntate. Salvale su QDN."
|
||||
},
|
||||
"settings": "impostazioni",
|
||||
"supply": "disponibilità",
|
||||
"theme": {
|
||||
"dark": "modalità scura",
|
||||
"light": "modalità chiara"
|
||||
},
|
||||
"time": {
|
||||
"day_one": "{{count}} giorno",
|
||||
"day_other": "{{count}} giorni",
|
||||
"hour_one": "{{count}} ora",
|
||||
"hour_other": "{{count}} ore",
|
||||
"minute_one": "{{count}} minuto",
|
||||
"minute_other": "{{count}} minuti"
|
||||
},
|
||||
"title": "titolo",
|
||||
"tutorial": "tutorial",
|
||||
"user_lookup": "ricerca utente",
|
||||
"wallet": {
|
||||
"wallet": "wallet",
|
||||
"wallet_other": "wallet"
|
||||
},
|
||||
"welcome": "benvenuto"
|
||||
}
|
65
public/locales/it/group.json
Normal file
@ -0,0 +1,65 @@
|
||||
{
|
||||
"action": {
|
||||
"cancel_ban": "annulla ban",
|
||||
"create_group": "crea gruppo",
|
||||
"find_group": "trova gruppo",
|
||||
"join_group": "unisciti al gruppo",
|
||||
"invite_member": "invita membro",
|
||||
"refetch_page": "ricarica pagina",
|
||||
"return_to_thread": "torna ai thread"
|
||||
},
|
||||
"advanced_options": "opzioni avanzate",
|
||||
"approval_threshold": "soglia di Approvazione del gruppo (numero/percentuale di Admin che devono approvare una transazione)",
|
||||
"ban_list": "lista ban",
|
||||
"block_delay": {
|
||||
"minimum": "ritardo minimo dei blocchi per Approvazione di Transazioni di Gruppo",
|
||||
"maximum": "ritardo massimo dei blocchi per Approvazione di Transazioni di Gruppo"
|
||||
},
|
||||
"group": {
|
||||
"closed": "chiuso (privato) - gli utenti necessitano di permesso per unirsi",
|
||||
"description": "descrizione del gruppo",
|
||||
"invites": "inviti del gruppo",
|
||||
"management": "gestione del gruppo",
|
||||
"name": "nome del gruppo",
|
||||
"open": "aperto (pubblico)",
|
||||
"type": "tipo di gruppo"
|
||||
},
|
||||
"invitation_expiry": "tempo di scadenza dell'invito",
|
||||
"join_requests": "richieste di adesione",
|
||||
"question": {
|
||||
"cancel_ban": "vuoi eseguire una transazione CANCEL_GROUP_BAN?",
|
||||
"create_group": "vuoi eseguire una transazione CREATE_GROUP?",
|
||||
"group_invite": "vuoi eseguire una transazione GROUP_INVITE?",
|
||||
"join_group": "vuoi eseguire una transazione JOIN_GROUP?",
|
||||
"provide_thread": "per favore fornisci un titolo per il thread"
|
||||
},
|
||||
"message": {
|
||||
"generic": {
|
||||
"encryption_key": "la prima chiave di cifratura comune del gruppo è in fase di creazione. Attendere alcuni minuti affinché venga recuperata dalla rete. Controllo ogni 2 minuti...",
|
||||
"group_invited_you": "{{group}} ti ha invitato",
|
||||
"no_display": "niente da visualizzare",
|
||||
"no_selection": "nessun gruppo selezionato",
|
||||
"not_part_group": "non fai parte del gruppo cifrato dei membri. Attendi che un amministratore ri-codifichi le chiavi.",
|
||||
"only_encrypted": "verranno visualizzati solo i messaggi non cifrati.",
|
||||
"setting_group": "configurazione del gruppo... attendere prego."
|
||||
},
|
||||
"error": {
|
||||
"access_name": "impossibile inviare un messaggio senza accesso al tuo nome",
|
||||
"description_required": "per favore fornisci una descrizione",
|
||||
"group_info": "impossibile accedere alle informazioni del gruppo",
|
||||
"name_required": "per favore fornisci un nome",
|
||||
"notify_admins": "prova a notificare un admin dalla lista di amministratori qui sotto:"
|
||||
},
|
||||
"success": {
|
||||
"group_creation": "gruppo creato con successo. Potrebbero volerci alcuni minuti affinché le modifiche si propaghino",
|
||||
"group_creation_name": "gruppo {{group_name}} creato: in attesa di conferma",
|
||||
"group_creation_label": "gruppo {{name}} creato: successo!",
|
||||
"group_invite": "invito inviato con successo a {{value}}. Potrebbero volerci alcuni minuti affinché le modifiche si propaghino",
|
||||
"join_creation": "richiesta di adesione al gruppo inviata con successo. Potrebbero volerci alcuni minuti affinché le modifiche si propaghino",
|
||||
"group_join_name": "entrato nel gruppo {{group_name}}: in attesa di conferma",
|
||||
"group_join_label": "entrato nel gruppo {{name}}: successo!",
|
||||
"loading_threads": "caricamento thread... attendere prego.",
|
||||
"unbanned_user": "utente sbannato con successo. Potrebbero volerci alcuni minuti affinché le modifiche si propaghino"
|
||||
}
|
||||
}
|
||||
}
|
21
public/locales/it/tutorial.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"1_getting_started": "1. Come iniziare",
|
||||
"2_overview": "2. Overview",
|
||||
"3_groups": "3. I gruppi in Qortal",
|
||||
"4_obtain_qort": "4. Ottenere Qort",
|
||||
"account_creation": "creazione account",
|
||||
"important_info": "important information!",
|
||||
"apps": {
|
||||
"dashboard": "1. Dashboard delle app",
|
||||
"navigation": "2. Navigation tra le app"
|
||||
},
|
||||
"initial": {
|
||||
"6_qort": "avere almeno 6 QORT nel proprio wallet",
|
||||
"explore": "esplora",
|
||||
"general_chat": "chat generale",
|
||||
"getting_started": "come iniziare",
|
||||
"register_name": "registra un nome",
|
||||
"see_apps": "vedi le apps",
|
||||
"trade_qort": "scambia i QORT"
|
||||
}
|
||||
}
|
43
public/locales/ru/auth.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"account": {
|
||||
"your": "Ваш аккаунт",
|
||||
"account_many": "аккаунты",
|
||||
"account_one": "аккаунт"
|
||||
},
|
||||
"advanced_users": "для продвинутых пользователей",
|
||||
"apikey": {
|
||||
"alternative": "альтернатива: выбрать файл",
|
||||
"change": "изменить API-ключ",
|
||||
"enter": "введите API-ключ",
|
||||
"import": "импортировать API-ключ",
|
||||
"key": "API-ключ",
|
||||
"select_valid": "выберите действительный API-ключ"
|
||||
},
|
||||
"authenticate": "аутентификация",
|
||||
"build_version": "версия сборки",
|
||||
"create_account": "создать аккаунт",
|
||||
"download_account": "скачать аккаунт",
|
||||
"keep_secure": "Храните файл аккаунта в безопасности",
|
||||
"node": {
|
||||
"choose": "выбрать пользовательский узел",
|
||||
"custom_many": "пользовательские узлы",
|
||||
"use_custom": "использовать пользовательский узел",
|
||||
"use_local": "использовать локальный узел",
|
||||
"using": "используется узел",
|
||||
"using_public": "используется публичный узел"
|
||||
},
|
||||
"password": "пароль",
|
||||
"password_confirmation": "подтвердите пароль",
|
||||
"return_to_list": "вернуться к списку",
|
||||
"wallet": {
|
||||
"password_confirmation": "подтвердите пароль кошелька",
|
||||
"password": "пароль кошелька",
|
||||
"keep_password": "сохранить текущий пароль",
|
||||
"new_password": "новый пароль",
|
||||
"error": {
|
||||
"missing_new_password": "пожалуйста, введите новый пароль",
|
||||
"missing_password": "пожалуйста, введите ваш пароль"
|
||||
}
|
||||
},
|
||||
"welcome": "добро пожаловать в"
|
||||
}
|
71
public/locales/ru/core.json
Normal file
@ -0,0 +1,71 @@
|
||||
{
|
||||
"add": "добавить",
|
||||
"cancel": "отмена",
|
||||
"choose": "выбрать",
|
||||
"close": "закрыть",
|
||||
"continue": "продолжить",
|
||||
"core": {
|
||||
"block_height": "высота блока",
|
||||
"information": "информация ядра",
|
||||
"peers": "подключенные узлы",
|
||||
"version": "версия ядра"
|
||||
},
|
||||
"description": "описание",
|
||||
"edit": "редактировать",
|
||||
"export": "экспорт",
|
||||
"import": "импорт",
|
||||
"last_height": "последняя высота",
|
||||
"loading": "загрузка...",
|
||||
"logout": "выйти",
|
||||
"minting_status": "статус чеканки",
|
||||
"payment_notification": "уведомление о платеже",
|
||||
"price": "цена",
|
||||
"q_mail": "q-mail",
|
||||
"result": {
|
||||
"error": {
|
||||
"generic": "произошла ошибка",
|
||||
"incorrect_password": "неверный пароль",
|
||||
"save_qdn": "не удалось сохранить в QDN"
|
||||
},
|
||||
"status": {
|
||||
"minting": "(чеканка)",
|
||||
"not_minting": "(не чеканится)",
|
||||
"synchronized": "синхронизировано",
|
||||
"synchronizing": "синхронизация"
|
||||
},
|
||||
"success": {
|
||||
"publish_qdn": "успешно опубликовано в QDN"
|
||||
}
|
||||
},
|
||||
"save_options": {
|
||||
"no_pinned_changes": "у вас нет изменений в закреплённых приложениях",
|
||||
"overwrite_changes": "приложению не удалось загрузить ваши закреплённые приложения, сохранённые в QDN. Хотите перезаписать эти изменения?",
|
||||
"overwrite_qdn": "перезаписать в QDN",
|
||||
"publish_qdn": "хотите опубликовать свои настройки в QDN (зашифровано)?",
|
||||
"qdn": "использовать сохранение в QDN",
|
||||
"register_name": "вам необходимо зарегистрированное имя Qortal для сохранения закреплённых приложений в QDN.",
|
||||
"reset_pinned": "не устраивают текущие локальные изменения? Хотите сбросить до приложений по умолчанию?",
|
||||
"reset_qdn": "не устраивают текущие локальные изменения? Хотите сбросить до сохранённых в QDN приложений?",
|
||||
"revert_default": "сбросить до стандартных",
|
||||
"revert_qdn": "сбросить до QDN",
|
||||
"save_qdn": "сохранить в QDN",
|
||||
"save": "сохранить",
|
||||
"settings": "вы используете метод экспорта/импорта для сохранения настроек.",
|
||||
"unsaved_changes": "у вас есть несохранённые изменения в закреплённых приложениях. Сохраните их в QDN."
|
||||
},
|
||||
"settings": "настройки",
|
||||
"supply": "предложение",
|
||||
"theme": {
|
||||
"dark": "тёмная тема",
|
||||
"light": "светлая тема"
|
||||
},
|
||||
"title": "заголовок",
|
||||
"tutorial": "учебник",
|
||||
"user_lookup": "поиск пользователя",
|
||||
"wallet": {
|
||||
"backup_wallet": "резервная копия кошелька",
|
||||
"wallet": "кошелёк",
|
||||
"wallet_other": "кошельки"
|
||||
},
|
||||
"welcome": "добро пожаловать"
|
||||
}
|
21
public/locales/ru/tutorial.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"1_getting_started": "1. Начало работы",
|
||||
"2_overview": "2. Обзор",
|
||||
"3_groups": "3. Группы Qortal",
|
||||
"4_obtain_qort": "4. Получение QORT",
|
||||
"account_creation": "создание аккаунта",
|
||||
"important_info": "важная информация!",
|
||||
"apps": {
|
||||
"dashboard": "1. Панель приложений",
|
||||
"navigation": "2. Навигация по приложениям"
|
||||
},
|
||||
"initial": {
|
||||
"6_qort": "иметь не менее 6 QORT в кошельке",
|
||||
"explore": "исследовать",
|
||||
"general_chat": "общий чат",
|
||||
"getting_started": "начало работы",
|
||||
"register_name": "зарегистрировать имя",
|
||||
"see_apps": "посмотреть приложения",
|
||||
"trade_qort": "обмен QORT"
|
||||
}
|
||||
}
|
@ -1,229 +0,0 @@
|
||||
import {
|
||||
AppBar,
|
||||
Button,
|
||||
Toolbar,
|
||||
Typography,
|
||||
Box,
|
||||
TextField,
|
||||
InputLabel,
|
||||
} from "@mui/material";
|
||||
import { styled } from "@mui/system";
|
||||
|
||||
export const AppContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexDirection: 'column',
|
||||
width: "100vw",
|
||||
background: "rgba(39, 40, 44, 1)",
|
||||
height: "100vh",
|
||||
radius: "15px",
|
||||
overflow: 'hidden'
|
||||
}));
|
||||
export const AuthenticatedContainer = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
justifyContent: "space-between"
|
||||
}));
|
||||
export const AuthenticatedContainerInnerLeft = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexDirection: 'column',
|
||||
height: "100%",
|
||||
width: "100%"
|
||||
}));
|
||||
export const AuthenticatedContainerInnerRight = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexDirection: 'column',
|
||||
width: "60px",
|
||||
height: "100%",
|
||||
background: "rgba(0, 0, 0, 0.1)"
|
||||
|
||||
}));
|
||||
export const AuthenticatedContainerInnerTop = styled(Box)(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
width: "100%px",
|
||||
height: "60px",
|
||||
background: "rgba(0, 0, 0, 0.1)",
|
||||
padding: '20px'
|
||||
}));
|
||||
|
||||
export const TextP = styled(Typography)(({ theme }) => ({
|
||||
fontSize: "13px",
|
||||
fontWeight: 600,
|
||||
fontFamily: "Inter",
|
||||
color: "white"
|
||||
}));
|
||||
|
||||
export const TextItalic = styled("span")(({ theme }) => ({
|
||||
fontSize: "13px",
|
||||
fontWeight: 600,
|
||||
fontFamily: "Inter",
|
||||
color: "white",
|
||||
fontStyle: "italic"
|
||||
}));
|
||||
|
||||
export const TextSpan = styled("span")(({ theme }) => ({
|
||||
fontSize: "13px",
|
||||
fontFamily: "Inter",
|
||||
fontWeight: 800,
|
||||
color: "white"
|
||||
}));
|
||||
|
||||
export const AddressBox = styled(Box)`
|
||||
display: flex;
|
||||
border: 1px solid var(--50-white, rgba(255, 255, 255, 0.5));
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: auto;
|
||||
height: 25px;
|
||||
padding: 5px 15px 5px 15px;
|
||||
gap: 5px;
|
||||
border-radius: 100px;
|
||||
font-family: Inter;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
line-height: 14.52px;
|
||||
text-align: left;
|
||||
color: var(--50-white, rgba(255, 255, 255, 0.5));
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
&:hover {
|
||||
background-color: rgba(41, 41, 43, 1);
|
||||
color: white;
|
||||
svg path {
|
||||
fill: white; // Fill color changes to white on hover
|
||||
}
|
||||
}
|
||||
|
||||
`
|
||||
|
||||
export const CustomButton = styled(Box)`
|
||||
|
||||
/* Authenticate */
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
padding: 15px 20px;
|
||||
gap: 10px;
|
||||
|
||||
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.5);
|
||||
filter: drop-shadow(1px 4px 10.5px rgba(0, 0, 0, 0.3));
|
||||
border-radius: 5px;
|
||||
|
||||
display: inline-flex;
|
||||
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
width: fit-content;
|
||||
transition: all 0.2s;
|
||||
color: black;
|
||||
min-width: 160px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
font-family: Inter;
|
||||
color: white;
|
||||
text-align: center;
|
||||
&:hover {
|
||||
background-color: rgba(41, 41, 43, 1);
|
||||
color: white;
|
||||
svg path {
|
||||
fill: white; // Fill color changes to white on hover
|
||||
}
|
||||
}
|
||||
`;
|
||||
interface CustomButtonProps {
|
||||
bgColor?: string;
|
||||
color?: string;
|
||||
}
|
||||
export const CustomButtonAccept = styled(Box)<CustomButtonProps>(
|
||||
({ bgColor, color }) => ({
|
||||
boxSizing: "border-box",
|
||||
padding: "15px 20px",
|
||||
gap: "10px",
|
||||
border: "0.5px solid rgba(255, 255, 255, 0.5)",
|
||||
filter: "drop-shadow(1px 4px 10.5px rgba(0,0,0,0.3))",
|
||||
borderRadius: 5,
|
||||
display: "inline-flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
width: "fit-content",
|
||||
transition: "all 0.2s",
|
||||
minWidth: 160,
|
||||
cursor: "pointer",
|
||||
fontWeight: 600,
|
||||
fontFamily: "Inter",
|
||||
textAlign: "center",
|
||||
opacity: 0.7,
|
||||
// Use the passed-in props or fallback defaults
|
||||
backgroundColor: bgColor || "transparent",
|
||||
color: color || "white",
|
||||
|
||||
"&:hover": {
|
||||
opacity: 1,
|
||||
backgroundColor: bgColor
|
||||
? bgColor
|
||||
: "rgba(41, 41, 43, 1)", // fallback hover bg
|
||||
color: color || "white",
|
||||
svg: {
|
||||
path: {
|
||||
fill: color || "white",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
export const CustomInput = styled(TextField)({
|
||||
width: "183px", // Adjust the width as needed
|
||||
borderRadius: "5px",
|
||||
// backgroundColor: "rgba(30, 30, 32, 1)",
|
||||
outline: "none",
|
||||
input: {
|
||||
fontSize: 10,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: 400,
|
||||
color: "white",
|
||||
"&::placeholder": {
|
||||
fontSize: 16,
|
||||
color: "rgba(255, 255, 255, 0.2)",
|
||||
},
|
||||
outline: "none",
|
||||
padding: "10px",
|
||||
},
|
||||
"& .MuiOutlinedInput-root": {
|
||||
"& fieldset": {
|
||||
border: '0.5px solid rgba(255, 255, 255, 0.5)',
|
||||
},
|
||||
"&:hover fieldset": {
|
||||
border: '0.5px solid rgba(255, 255, 255, 0.5)',
|
||||
},
|
||||
"&.Mui-focused fieldset": {
|
||||
border: '0.5px solid rgba(255, 255, 255, 0.5)',
|
||||
},
|
||||
},
|
||||
"& .MuiInput-underline:before": {
|
||||
borderBottom: "none",
|
||||
},
|
||||
"& .MuiInput-underline:hover:not(.Mui-disabled):before": {
|
||||
borderBottom: "none",
|
||||
},
|
||||
"& .MuiInput-underline:after": {
|
||||
borderBottom: "none",
|
||||
},
|
||||
});
|
||||
|
||||
export const CustomLabel = styled(InputLabel)`
|
||||
font-weight: 400;
|
||||
font-family: Inter;
|
||||
font-size: 10px;
|
||||
line-height: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
|
||||
`
|
4993
src/App.tsx
629
src/Wallets.tsx
@ -1,48 +1,59 @@
|
||||
import React, { useContext, useEffect, useRef, useState } from "react";
|
||||
import List from "@mui/material/List";
|
||||
import ListItem from "@mui/material/ListItem";
|
||||
import Divider from "@mui/material/Divider";
|
||||
import ListItemText from "@mui/material/ListItemText";
|
||||
import ListItemAvatar from "@mui/material/ListItemAvatar";
|
||||
import Avatar from "@mui/material/Avatar";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { Box, Button, ButtonBase, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, Input } from "@mui/material";
|
||||
import { CustomButton } from "./App-styles";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import { Label } from "./components/Group/AddGroup";
|
||||
import { Spacer } from "./common/Spacer";
|
||||
import { getWallets, storeWallets, walletVersion } from "./background";
|
||||
import { useModal } from "./common/useModal";
|
||||
import PhraseWallet from "./utils/generateWallet/phrase-wallet";
|
||||
import { decryptStoredWalletFromSeedPhrase } from "./utils/decryptWallet";
|
||||
import { crypto } from "./constants/decryptWallet";
|
||||
import { LoadingButton } from "@mui/lab";
|
||||
import { PasswordField } from "./components";
|
||||
import { HtmlTooltip } from "./ExtStates/NotAuthenticated";
|
||||
import { GlobalContext } from "./App";
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import List from '@mui/material/List';
|
||||
import ListItem from '@mui/material/ListItem';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import ListItemAvatar from '@mui/material/ListItemAvatar';
|
||||
import Avatar from '@mui/material/Avatar';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
ButtonBase,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
IconButton,
|
||||
Input,
|
||||
useTheme,
|
||||
} from '@mui/material';
|
||||
import { CustomButton } from './styles/App-styles';
|
||||
import { useDropzone } from 'react-dropzone';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
import { Label } from './components/Group/AddGroup';
|
||||
import { Spacer } from './common/Spacer';
|
||||
import { getWallets, storeWallets, walletVersion } from './background';
|
||||
import { useModal } from './common/useModal';
|
||||
import PhraseWallet from './utils/generateWallet/phrase-wallet';
|
||||
import { decryptStoredWalletFromSeedPhrase } from './utils/decryptWallet';
|
||||
import { crypto } from './constants/decryptWallet';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { PasswordField } from './components';
|
||||
import { HtmlTooltip } from './ExtStates/NotAuthenticated';
|
||||
import { MyContext } from './App';
|
||||
|
||||
const parsefilenameQortal = (filename)=> {
|
||||
return filename.startsWith("qortal_backup_") ? filename.slice(14) : filename;
|
||||
}
|
||||
const parsefilenameQortal = (filename) => {
|
||||
return filename.startsWith('qortal_backup_') ? filename.slice(14) : filename;
|
||||
};
|
||||
|
||||
export const Wallets = ({ setExtState, setRawWallet, rawWallet }) => {
|
||||
const [wallets, setWallets] = useState([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [seedValue, setSeedValue] = useState("");
|
||||
const [seedName, setSeedName] = useState("");
|
||||
const [seedError, setSeedError] = useState("");
|
||||
const { hasSeenGettingStarted } = useContext(GlobalContext);
|
||||
const [seedValue, setSeedValue] = useState('');
|
||||
const [seedName, setSeedName] = useState('');
|
||||
const [seedError, setSeedError] = useState('');
|
||||
const { hasSeenGettingStarted } = useContext(MyContext);
|
||||
|
||||
const [password, setPassword] = useState("");
|
||||
const [password, setPassword] = useState('');
|
||||
const [isOpenSeedModal, setIsOpenSeedModal] = useState(false);
|
||||
const [isLoadingEncryptSeed, setIsLoadingEncryptSeed] = useState(false);
|
||||
|
||||
const { isShow, onCancel, onOk, show, } = useModal();
|
||||
const theme = useTheme();
|
||||
const { isShow, onCancel, onOk, show } = useModal();
|
||||
|
||||
const { getRootProps, getInputProps } = useDropzone({
|
||||
accept: {
|
||||
"application/json": [".json"], // Only accept JSON files
|
||||
'application/json': ['.json'], // Only accept JSON files
|
||||
},
|
||||
onDrop: async (acceptedFiles) => {
|
||||
const files: any = acceptedFiles;
|
||||
@ -53,8 +64,8 @@ export const Wallets = ({ setExtState, setRawWallet, rawWallet }) => {
|
||||
const fileContents = await new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onabort = () => reject("File reading was aborted");
|
||||
reader.onerror = () => reject("File reading has failed");
|
||||
reader.onabort = () => reject('File reading was aborted');
|
||||
reader.onerror = () => reject('File reading has failed');
|
||||
reader.onload = () => {
|
||||
// Resolve the promise with the reader result when reading completes
|
||||
resolve(reader.result);
|
||||
@ -63,9 +74,9 @@ export const Wallets = ({ setExtState, setRawWallet, rawWallet }) => {
|
||||
// Read the file as text
|
||||
reader.readAsText(file);
|
||||
});
|
||||
if (typeof fileContents !== "string") continue;
|
||||
const parsedData = JSON.parse(fileContents)
|
||||
importedWallets.push({...parsedData, filename: file?.name});
|
||||
if (typeof fileContents !== 'string') continue;
|
||||
const parsedData = JSON.parse(fileContents);
|
||||
importedWallets.push({ ...parsedData, filename: file?.name });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
@ -108,83 +119,85 @@ export const Wallets = ({ setExtState, setRawWallet, rawWallet }) => {
|
||||
});
|
||||
};
|
||||
|
||||
const handleSetSeedValue = async ()=> {
|
||||
const handleSetSeedValue = async () => {
|
||||
try {
|
||||
setIsOpenSeedModal(true)
|
||||
const {seedValue, seedName, password} = await show({
|
||||
message: "",
|
||||
publishFee: "",
|
||||
setIsOpenSeedModal(true);
|
||||
const { seedValue, seedName, password } = await show({
|
||||
message: '',
|
||||
publishFee: '',
|
||||
});
|
||||
setIsLoadingEncryptSeed(true)
|
||||
const res = await decryptStoredWalletFromSeedPhrase(seedValue)
|
||||
setIsLoadingEncryptSeed(true);
|
||||
const res = await decryptStoredWalletFromSeedPhrase(seedValue);
|
||||
const wallet2 = new PhraseWallet(res, walletVersion);
|
||||
const wallet = await wallet2.generateSaveWalletData(
|
||||
password,
|
||||
crypto.kdfThreads,
|
||||
() => {}
|
||||
);
|
||||
if(wallet?.address0){
|
||||
setWallets([...wallets, {
|
||||
...wallet,
|
||||
name: seedName
|
||||
}]);
|
||||
setIsOpenSeedModal(false)
|
||||
setSeedValue('')
|
||||
setSeedName('')
|
||||
setPassword('')
|
||||
setSeedError('')
|
||||
if (wallet?.address0) {
|
||||
setWallets([
|
||||
...wallets,
|
||||
{
|
||||
...wallet,
|
||||
name: seedName,
|
||||
},
|
||||
]);
|
||||
setIsOpenSeedModal(false);
|
||||
setSeedValue('');
|
||||
setSeedName('');
|
||||
setPassword('');
|
||||
setSeedError('');
|
||||
} else {
|
||||
setSeedError('Could not create account.')
|
||||
setSeedError('Could not create account.');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
setSeedError(error?.message || 'Could not create account.')
|
||||
setSeedError(error?.message || 'Could not create account.');
|
||||
} finally {
|
||||
setIsLoadingEncryptSeed(false)
|
||||
setIsLoadingEncryptSeed(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const selectedWalletFunc = (wallet) => {
|
||||
setRawWallet(wallet);
|
||||
setExtState("wallet-dropped");
|
||||
setExtState('wallet-dropped');
|
||||
};
|
||||
|
||||
useEffect(()=> {
|
||||
setIsLoading(true)
|
||||
getWallets().then((res)=> {
|
||||
|
||||
if(res && Array.isArray(res)){
|
||||
setWallets(res)
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
getWallets()
|
||||
.then((res) => {
|
||||
if (res && Array.isArray(res)) {
|
||||
setWallets(res);
|
||||
}
|
||||
setIsLoading(false)
|
||||
}).catch((error)=> {
|
||||
console.error(error)
|
||||
setIsLoading(false)
|
||||
})
|
||||
}, [])
|
||||
setIsLoading(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
setIsLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(()=> {
|
||||
if(!isLoading && wallets && Array.isArray(wallets)){
|
||||
storeWallets(wallets)
|
||||
useEffect(() => {
|
||||
if (!isLoading && wallets && Array.isArray(wallets)) {
|
||||
storeWallets(wallets);
|
||||
}
|
||||
}, [wallets, isLoading])
|
||||
}, [wallets, isLoading]);
|
||||
|
||||
if(isLoading) return null
|
||||
if (isLoading) return null;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{(wallets?.length === 0 ||
|
||||
!wallets) ? (
|
||||
<>
|
||||
<Typography>No accounts saved</Typography>
|
||||
<Spacer height="75px" />
|
||||
</>
|
||||
): (
|
||||
<>
|
||||
<Typography>Your saved accounts</Typography>
|
||||
<Spacer height="30px" />
|
||||
</>
|
||||
)}
|
||||
{wallets?.length === 0 || !wallets ? (
|
||||
<>
|
||||
<Typography>No accounts saved</Typography>
|
||||
<Spacer height="75px" />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Typography>Your saved accounts</Typography>
|
||||
<Spacer height="30px" />
|
||||
</>
|
||||
)}
|
||||
|
||||
{rawWallet && (
|
||||
<Box>
|
||||
@ -196,175 +209,201 @@ export const Wallets = ({ setExtState, setRawWallet, rawWallet }) => {
|
||||
</Box>
|
||||
)}
|
||||
{wallets?.length > 0 && (
|
||||
<List
|
||||
sx={{
|
||||
width: "100%",
|
||||
maxWidth: "500px",
|
||||
maxHeight: "60vh",
|
||||
overflowY: "auto",
|
||||
overflowX: "hidden",
|
||||
backgroundColor: "rgb(30 30 32 / 70%)",
|
||||
|
||||
}}
|
||||
>
|
||||
{wallets?.map((wallet, idx) => {
|
||||
return (
|
||||
<>
|
||||
<WalletItem
|
||||
setSelectedWallet={selectedWalletFunc}
|
||||
key={wallet?.address0}
|
||||
wallet={wallet}
|
||||
idx={idx}
|
||||
updateWalletItem={updateWalletItem}
|
||||
/>
|
||||
<Divider variant="inset" component="li" />
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
<List
|
||||
sx={{
|
||||
width: '100%',
|
||||
maxWidth: '500px',
|
||||
maxHeight: '60vh',
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
}}
|
||||
>
|
||||
{wallets?.map((wallet, idx) => {
|
||||
return (
|
||||
<>
|
||||
<WalletItem
|
||||
setSelectedWallet={selectedWalletFunc}
|
||||
key={wallet?.address0}
|
||||
wallet={wallet}
|
||||
idx={idx}
|
||||
updateWalletItem={updateWalletItem}
|
||||
/>
|
||||
<Divider variant="inset" component="li" />
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
)}
|
||||
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
alignItems: "center",
|
||||
display: 'flex',
|
||||
gap: '10px',
|
||||
alignItems: 'center',
|
||||
position: wallets?.length === 0 ? 'relative' : 'fixed',
|
||||
bottom: wallets?.length === 0 ? 'unset' : '20px',
|
||||
right: wallets?.length === 0 ? 'unset' : '20px'
|
||||
bottom: wallets?.length === 0 ? 'unset' : '20px',
|
||||
right: wallets?.length === 0 ? 'unset' : '20px',
|
||||
}}
|
||||
>
|
||||
<HtmlTooltip
|
||||
disableHoverListener={hasSeenGettingStarted === true}
|
||||
|
||||
title={
|
||||
<React.Fragment>
|
||||
<Typography color="inherit" sx={{
|
||||
fontSize: '16px'
|
||||
}}>Already have a Qortal account? Enter your secret backup phrase here to access it. This phrase is one of the ways to recover your account.</Typography>
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<CustomButton onClick={handleSetSeedValue} sx={{
|
||||
padding: '10px'
|
||||
}} >
|
||||
|
||||
Add seed-phrase
|
||||
</CustomButton>
|
||||
</HtmlTooltip>
|
||||
<HtmlTooltip
|
||||
disableHoverListener={hasSeenGettingStarted === true}
|
||||
|
||||
title={
|
||||
<React.Fragment>
|
||||
<Typography color="inherit" sx={{
|
||||
fontSize: '16px'
|
||||
}}>Use this option to connect additional Qortal wallets you've already made, in order to login with them afterwards. You will need access to your backup JSON file in order to do so.</Typography>
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<CustomButton sx={{
|
||||
padding: '10px'
|
||||
}} {...getRootProps()}>
|
||||
<input {...getInputProps()} />
|
||||
Add account
|
||||
</CustomButton>
|
||||
disableHoverListener={hasSeenGettingStarted === true}
|
||||
title={
|
||||
<React.Fragment>
|
||||
<Typography
|
||||
color="inherit"
|
||||
sx={{
|
||||
fontSize: '16px',
|
||||
}}
|
||||
>
|
||||
Already have a Qortal account? Enter your secret backup phrase
|
||||
here to access it. This phrase is one of the ways to recover
|
||||
your account.
|
||||
</Typography>
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<CustomButton
|
||||
onClick={handleSetSeedValue}
|
||||
sx={{
|
||||
padding: '10px',
|
||||
display: 'inline',
|
||||
}}
|
||||
>
|
||||
Add seed-phrase
|
||||
</CustomButton>
|
||||
</HtmlTooltip>
|
||||
|
||||
<HtmlTooltip
|
||||
disableHoverListener={hasSeenGettingStarted === true}
|
||||
title={
|
||||
<React.Fragment>
|
||||
<Typography
|
||||
color="inherit"
|
||||
sx={{
|
||||
fontSize: '16px',
|
||||
}}
|
||||
>
|
||||
Use this option to connect additional Qortal wallets you've
|
||||
already made, in order to login with them afterwards. You will
|
||||
need access to your backup JSON file in order to do so.
|
||||
</Typography>
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<CustomButton
|
||||
sx={{
|
||||
padding: '10px',
|
||||
}}
|
||||
{...getRootProps()}
|
||||
>
|
||||
<input {...getInputProps()} />
|
||||
Add account
|
||||
</CustomButton>
|
||||
</HtmlTooltip>
|
||||
</Box>
|
||||
|
||||
<Dialog
|
||||
open={isOpenSeedModal}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && seedValue && seedName && password) {
|
||||
onOk({seedValue, seedName, password});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DialogTitle id="alert-dialog-title">
|
||||
Type or paste in your seed-phrase
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
|
||||
}}
|
||||
>
|
||||
<Dialog
|
||||
open={isOpenSeedModal}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && seedValue && seedName && password) {
|
||||
onOk({ seedValue, seedName, password });
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DialogTitle id="alert-dialog-title">
|
||||
Type or paste in your seed-phrase
|
||||
</DialogTitle>
|
||||
|
||||
<DialogContent>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<Label>Name</Label>
|
||||
<Input
|
||||
placeholder="Name"
|
||||
value={seedName}
|
||||
onChange={(e) => setSeedName(e.target.value)}
|
||||
/>
|
||||
<Spacer height="7px" />
|
||||
<Label>Seed-phrase</Label>
|
||||
<PasswordField
|
||||
placeholder="Seed-phrase"
|
||||
<Input
|
||||
placeholder="Name"
|
||||
value={seedName}
|
||||
onChange={(e) => setSeedName(e.target.value)}
|
||||
/>
|
||||
|
||||
<Spacer height="7px" />
|
||||
|
||||
<Label>Seed-phrase</Label>
|
||||
<PasswordField
|
||||
placeholder="Seed-phrase"
|
||||
id="standard-adornment-password"
|
||||
value={seedValue}
|
||||
onChange={(e) => setSeedValue(e.target.value)}
|
||||
autoComplete="off"
|
||||
sx={{
|
||||
width: '100%'
|
||||
width: '100%',
|
||||
}}
|
||||
/>
|
||||
<Spacer height="7px" />
|
||||
|
||||
<Label>Choose new password</Label>
|
||||
<PasswordField
|
||||
<Spacer height="7px" />
|
||||
|
||||
<Label>Choose new password</Label>
|
||||
<PasswordField
|
||||
id="standard-adornment-password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
autoComplete="off"
|
||||
sx={{
|
||||
width: '100%'
|
||||
width: '100%',
|
||||
}}
|
||||
/>
|
||||
|
||||
</Box>
|
||||
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button disabled={isLoadingEncryptSeed} variant="contained" onClick={()=> {
|
||||
setIsOpenSeedModal(false)
|
||||
setSeedValue('')
|
||||
setSeedName('')
|
||||
setPassword('')
|
||||
setSeedError('')
|
||||
}}>
|
||||
Close
|
||||
</Button>
|
||||
<LoadingButton
|
||||
</Box>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
disabled={isLoadingEncryptSeed}
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
setIsOpenSeedModal(false);
|
||||
setSeedValue('');
|
||||
setSeedName('');
|
||||
setPassword('');
|
||||
setSeedError('');
|
||||
}}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
<LoadingButton
|
||||
loading={isLoadingEncryptSeed}
|
||||
disabled={!seedValue || !seedName || !password}
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
if(!seedValue || !seedName || !password) return
|
||||
onOk({seedValue, seedName, password});
|
||||
}}
|
||||
autoFocus
|
||||
>
|
||||
Add
|
||||
</LoadingButton>
|
||||
<Typography sx={{
|
||||
fontSize: '14px',
|
||||
visibility: seedError ? 'visible' : 'hidden'
|
||||
}}>{seedError}</Typography>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
||||
disabled={!seedValue || !seedName || !password}
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
if (!seedValue || !seedName || !password) return;
|
||||
onOk({ seedValue, seedName, password });
|
||||
}}
|
||||
autoFocus
|
||||
>
|
||||
Add
|
||||
</LoadingButton>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: '14px',
|
||||
visibility: seedError ? 'visible' : 'hidden',
|
||||
}}
|
||||
>
|
||||
{seedError}
|
||||
</Typography>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</div>
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
const WalletItem = ({ wallet, updateWalletItem, idx, setSelectedWallet }) => {
|
||||
const [name, setName] = useState("");
|
||||
const [note, setNote] = useState("");
|
||||
const [name, setName] = useState('');
|
||||
const [note, setNote] = useState('');
|
||||
const [isEdit, setIsEdit] = useState(false);
|
||||
const theme = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
if (wallet?.name) {
|
||||
@ -382,71 +421,78 @@ const WalletItem = ({ wallet, updateWalletItem, idx, setSelectedWallet }) => {
|
||||
}}
|
||||
sx={{
|
||||
width: '100%',
|
||||
padding: '10px'
|
||||
padding: '10px',
|
||||
}}
|
||||
|
||||
>
|
||||
<ListItem
|
||||
sx={{
|
||||
bgcolor: "background.paper",
|
||||
bgcolor: theme.palette.background.default,
|
||||
flexGrow: 1,
|
||||
"&:hover": { backgroundColor: "secondary.main", transform: "scale(1.01)" },
|
||||
transition: "all 0.1s ease-in-out",
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
transform: 'scale(1.01)',
|
||||
},
|
||||
transition: 'all 0.1s ease-in-out',
|
||||
}}
|
||||
|
||||
alignItems="flex-start"
|
||||
>
|
||||
<ListItemAvatar>
|
||||
<Avatar alt="" src="/static/images/avatar/1.jpg" />
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
|
||||
primary={wallet?.name ? wallet.name : wallet?.filename ? parsefilenameQortal(wallet?.filename) : "No name"}
|
||||
primary={
|
||||
wallet?.name
|
||||
? wallet.name
|
||||
: wallet?.filename
|
||||
? parsefilenameQortal(wallet?.filename)
|
||||
: 'No name'
|
||||
}
|
||||
secondary={
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
component="span"
|
||||
variant="body2"
|
||||
sx={{ color: "text.primary", display: "inline" }}
|
||||
sx={{ color: theme.palette.text.primary, display: 'inline' }}
|
||||
>
|
||||
{wallet?.address0}
|
||||
</Typography>
|
||||
{wallet?.note}
|
||||
<Typography sx={{
|
||||
textAlign: 'end',
|
||||
marginTop: '5px'
|
||||
}}>Login</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
textAlign: 'end',
|
||||
marginTop: '5px',
|
||||
}}
|
||||
>
|
||||
Login
|
||||
</Typography>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
<IconButton
|
||||
sx={{
|
||||
alignSelf: 'flex-start'
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsEdit(true);
|
||||
}}
|
||||
edge="end"
|
||||
aria-label="edit"
|
||||
>
|
||||
<EditIcon
|
||||
sx={{
|
||||
color: "white",
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
sx={{
|
||||
alignSelf: 'flex-start',
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsEdit(true);
|
||||
}}
|
||||
edge="end"
|
||||
aria-label="edit"
|
||||
>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
</ButtonBase>
|
||||
{isEdit && (
|
||||
<Box
|
||||
sx={{
|
||||
padding: "8px",
|
||||
padding: '8px',
|
||||
}}
|
||||
>
|
||||
<Label>Name</Label>
|
||||
@ -455,10 +501,12 @@ const WalletItem = ({ wallet, updateWalletItem, idx, setSelectedWallet }) => {
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
sx={{
|
||||
width: "100%",
|
||||
width: '100%',
|
||||
}}
|
||||
/>
|
||||
|
||||
<Spacer height="10px" />
|
||||
|
||||
<Label>Note</Label>
|
||||
<Input
|
||||
placeholder="Note"
|
||||
@ -468,48 +516,54 @@ const WalletItem = ({ wallet, updateWalletItem, idx, setSelectedWallet }) => {
|
||||
maxLength: 100,
|
||||
}}
|
||||
sx={{
|
||||
width: "100%",
|
||||
width: '100%',
|
||||
}}
|
||||
/>
|
||||
|
||||
<Spacer height="10px" />
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
justifyContent: "flex-end",
|
||||
width: "100%",
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
justifyContent: 'flex-end',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Button size="small" variant="contained" onClick={() => setIsEdit(false)}>
|
||||
<Button
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => setIsEdit(false)}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
<Button
|
||||
sx={{
|
||||
backgroundColor: 'var(--danger)',
|
||||
"&:hover": {
|
||||
backgroundColor: "var(--danger)",
|
||||
},
|
||||
"&:focus": {
|
||||
backgroundColor: "var(--danger)",
|
||||
},
|
||||
}}
|
||||
size="small"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.other.danger,
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.other.danger,
|
||||
},
|
||||
'&:focus': {
|
||||
backgroundColor: theme.palette.other.danger,
|
||||
},
|
||||
}}
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => updateWalletItem(idx, null)}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
<Button
|
||||
sx={{
|
||||
backgroundColor: "#5EB049",
|
||||
"&:hover": {
|
||||
backgroundColor: "#5EB049",
|
||||
},
|
||||
"&:focus": {
|
||||
backgroundColor: "#5EB049",
|
||||
},
|
||||
}}
|
||||
size="small"
|
||||
sx={{
|
||||
backgroundColor: '#5EB049',
|
||||
'&:hover': {
|
||||
backgroundColor: '#5EB049',
|
||||
},
|
||||
'&:focus': {
|
||||
backgroundColor: '#5EB049',
|
||||
},
|
||||
}}
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
updateWalletItem(idx, {
|
||||
@ -525,9 +579,6 @@ const WalletItem = ({ wallet, updateWalletItem, idx, setSelectedWallet }) => {
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
|
||||
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,10 @@
|
||||
import React from "react";
|
||||
import { useTheme } from '@mui/material';
|
||||
|
||||
export const AppsIcon = ({ height = 31, width = 31, color }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const setColor = color ? color : theme.palette.text.primary;
|
||||
|
||||
export const AppsIcon = ({ color, height = 31, width = 31 }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
@ -11,39 +15,39 @@ export const AppsIcon = ({ color, height = 31, width = 31 }) => {
|
||||
>
|
||||
<path
|
||||
d="M3.76596 7.53192C5.84584 7.53192 7.53192 5.84584 7.53192 3.76596C7.53192 1.68608 5.84584 0 3.76596 0C1.68608 0 0 1.68608 0 3.76596C0 5.84584 1.68608 7.53192 3.76596 7.53192Z"
|
||||
fill={color}
|
||||
fill={setColor}
|
||||
/>
|
||||
<path
|
||||
d="M15 7.53192C17.0799 7.53192 18.766 5.84584 18.766 3.76596C18.766 1.68608 17.0799 0 15 0C12.9201 0 11.2341 1.68608 11.2341 3.76596C11.2341 5.84584 12.9201 7.53192 15 7.53192Z"
|
||||
fill={color}
|
||||
fill={setColor}
|
||||
/>
|
||||
<path
|
||||
d="M26.234 7.53192C28.3139 7.53192 30 5.84584 30 3.76596C30 1.68608 28.3139 0 26.234 0C24.1542 0 22.4681 1.68608 22.4681 3.76596C22.4681 5.84584 24.1542 7.53192 26.234 7.53192Z"
|
||||
fill={color}
|
||||
fill={setColor}
|
||||
/>
|
||||
<path
|
||||
d="M3.76596 30.0001C5.84584 30.0001 7.53192 28.314 7.53192 26.2341C7.53192 24.1542 5.84584 22.4681 3.76596 22.4681C1.68608 22.4681 0 24.1542 0 26.2341C0 28.314 1.68608 30.0001 3.76596 30.0001Z"
|
||||
fill={color}
|
||||
fill={setColor}
|
||||
/>
|
||||
<path
|
||||
d="M15 30.0002C17.0799 30.0002 18.766 28.3141 18.766 26.2342C18.766 24.1543 17.0799 22.4683 15 22.4683C12.9201 22.4683 11.2341 24.1543 11.2341 26.2342C11.2341 28.3141 12.9201 30.0002 15 30.0002Z"
|
||||
fill={color}
|
||||
fill={setColor}
|
||||
/>
|
||||
<path
|
||||
d="M26.234 30.0002C28.3139 30.0002 30 28.3141 30 26.2342C30 24.1543 28.3139 22.4683 26.234 22.4683C24.1542 22.4683 22.4681 24.1543 22.4681 26.2342C22.4681 28.3141 24.1542 30.0002 26.234 30.0002Z"
|
||||
fill={color}
|
||||
fill={setColor}
|
||||
/>
|
||||
<path
|
||||
d="M3.76596 18.766C5.84584 18.766 7.53192 17.08 7.53192 15.0001C7.53192 12.9202 5.84584 11.2341 3.76596 11.2341C1.68608 11.2341 0 12.9202 0 15.0001C0 17.08 1.68608 18.766 3.76596 18.766Z"
|
||||
fill={color}
|
||||
fill={setColor}
|
||||
/>
|
||||
<path
|
||||
d="M15 18.766C17.0799 18.766 18.766 17.08 18.766 15.0001C18.766 12.9202 17.0799 11.2341 15 11.2341C12.9201 11.2341 11.2341 12.9202 11.2341 15.0001C11.2341 17.08 12.9201 18.766 15 18.766Z"
|
||||
fill={color}
|
||||
fill={setColor}
|
||||
/>
|
||||
<path
|
||||
d="M26.234 18.766C28.3139 18.766 30 17.08 30 15.0001C30 12.9202 28.3139 11.2341 26.234 11.2341C24.1542 11.2341 22.4681 12.9202 22.4681 15.0001C22.4681 17.08 24.1542 18.766 26.234 18.766Z"
|
||||
fill={color}
|
||||
fill={setColor}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
@ -1,12 +1,18 @@
|
||||
import React from 'react';
|
||||
|
||||
export const ChatIcon= ({ color = 'white', height = 15, width = 15 }) => {
|
||||
return (
|
||||
<svg width={width} height={height} viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.5 0C3.35915 0 0 3.35915 0 7.5V13.8169C0 14.4718 0.528169 15 1.1831 15H7.5C11.6408 15 15 11.6408 15 7.5C15 3.35915 11.6408 0 7.5 0ZM11.0915 10.669H3.90845C3.67606 10.669 3.48592 10.4789 3.48592 10.2465C3.48592 10.0141 3.67606 9.82394 3.90845 9.82394H11.0915C11.3239 9.82394 11.5141 10.0141 11.5141 10.2465C11.5141 10.4789 11.3239 10.669 11.0915 10.669ZM11.0915 8.34507H3.90845C3.67606 8.34507 3.48592 8.15493 3.48592 7.92254C3.48592 7.69014 3.67606 7.5 3.90845 7.5H11.0915C11.3239 7.5 11.5141 7.69014 11.5141 7.92254C11.5141 8.15493 11.3239 8.34507 11.0915 8.34507ZM11.0915 6.02113H3.90845C3.67606 6.02113 3.48592 5.83099 3.48592 5.59859C3.48592 5.3662 3.67606 5.17606 3.90845 5.17606H11.0915C11.3239 5.17606 11.5141 5.3662 11.5141 5.59859C11.5141 5.83099 11.3239 6.02113 11.0915 6.02113Z" fill={color}/>
|
||||
</svg>
|
||||
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
export const ChatIcon = ({ color = 'white', height = 15, width = 15 }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 15 15"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M7.5 0C3.35915 0 0 3.35915 0 7.5V13.8169C0 14.4718 0.528169 15 1.1831 15H7.5C11.6408 15 15 11.6408 15 7.5C15 3.35915 11.6408 0 7.5 0ZM11.0915 10.669H3.90845C3.67606 10.669 3.48592 10.4789 3.48592 10.2465C3.48592 10.0141 3.67606 9.82394 3.90845 9.82394H11.0915C11.3239 9.82394 11.5141 10.0141 11.5141 10.2465C11.5141 10.4789 11.3239 10.669 11.0915 10.669ZM11.0915 8.34507H3.90845C3.67606 8.34507 3.48592 8.15493 3.48592 7.92254C3.48592 7.69014 3.67606 7.5 3.90845 7.5H11.0915C11.3239 7.5 11.5141 7.69014 11.5141 7.92254C11.5141 8.15493 11.3239 8.34507 11.0915 8.34507ZM11.0915 6.02113H3.90845C3.67606 6.02113 3.48592 5.83099 3.48592 5.59859C3.48592 5.3662 3.67606 5.17606 3.90845 5.17606H11.0915C11.3239 5.17606 11.5141 5.3662 11.5141 5.59859C11.5141 5.83099 11.3239 6.02113 11.0915 6.02113Z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
33
src/assets/Icons/ComposeIcon.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import { useTheme } from '@mui/material';
|
||||
import { SVGProps } from './interfaces';
|
||||
|
||||
export const ComposeIcon: React.FC<SVGProps> = ({
|
||||
color,
|
||||
height = 20,
|
||||
width = 20,
|
||||
opacity,
|
||||
...children
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const setColor = color ? color : theme.palette.text.primary;
|
||||
const setOpacity = opacity ? opacity : 1;
|
||||
|
||||
return (
|
||||
<svg
|
||||
{...children}
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 64 64"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M50.3 3c1.5 0 3.9 0.6 5.5 1.4 1.5 0.7 3.3 2.5 4 4 0.6 1.4 1.2 3.7 1.2 5.1 0 1.4-0.6 3.7-1.4 5.3-0.8 1.5-9.9 11.1-39.1 40l-6.7 1.6c-3.8 0.9-7.9 1.6-9.3 1.6-1.8 0-2.5-0.5-2.5-2 0-1.1 0.7-5.3 3.2-16.5l18.1-18.4c10-10 19.6-19.2 21.2-20.2 1.7-1 4.2-1.9 5.8-1.9zm-8.4 11.3c0 0.7 1.5 2.7 3.3 4.4 1.8 1.8 3.9 3.3 4.6 3.3 0.6 0 2.3-1.4 3.7-3 1.4-1.7 2.5-4 2.5-5.3 0.1-1.2-0.7-3-1.7-3.9-1-1-2.8-1.8-4-1.8-1.2 0-3.5 1.2-5.3 2.6-1.7 1.4-3.1 3.1-3.1 3.7z"
|
||||
fill={setColor}
|
||||
opacity={setOpacity}
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
25
src/assets/Icons/CopyIcon.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import { useTheme } from '@mui/material';
|
||||
import React from 'react';
|
||||
|
||||
export const CopyIcon = ({ color, height = 11, width = 10 }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const setColor = color ? color : theme.palette.text.primary;
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 10 11"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M3.92857 0.5H8.57143C9.36071 0.5 10 1.13929 10 1.92857V6.57143C10 7.36071 9.36071 8 8.57143 8H8.21429V4.42857C8.21429 3.24643 7.25357 2.28571 6.07143 2.28571H2.5V1.92857C2.5 1.13929 3.13929 0.5 3.92857 0.5ZM1.42857 3H6.07143C6.86041 3 7.5 3.63959 7.5 4.42857V9.07143C7.5 9.86041 6.86041 10.5 6.07143 10.5H1.42857C0.639593 10.5 0 9.86041 0 9.07143V4.42857C0 3.63959 0.639593 3 1.42857 3Z"
|
||||
fill={setColor}
|
||||
fill-opacity="0.5"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
31
src/assets/Icons/CreateThreadIcon.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import { styled } from '@mui/system';
|
||||
import { SVGProps } from './interfaces';
|
||||
import { useTheme } from '@mui/material';
|
||||
|
||||
// Create a styled container with hover effects
|
||||
const SvgContainer = styled('svg')<{ color?: string }>(({ color }) => ({
|
||||
'& path': {
|
||||
fill: color,
|
||||
},
|
||||
}));
|
||||
export const CreateThreadIcon: React.FC<SVGProps> = ({ color }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const setColor = color || theme.palette.text.primary;
|
||||
return (
|
||||
<SvgContainer
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
color={setColor}
|
||||
>
|
||||
<path
|
||||
d="M0 9.80209V9.0205C0.0460138 8.67679 0.080024 8.31425 0.144043 7.98466C0.469856 6.30568 1.25577 4.79934 2.38071 3.6977C4.13924 1.88262 6.22987 0.985679 8.52256 0.674927C9.9086 0.485649 11.3116 0.565177 12.6758 0.910345C14.5124 1.34351 16.1889 2.2075 17.6053 3.67886C18.7276 4.84183 19.5319 6.24257 19.858 7.98466C19.918 8.31189 19.952 8.64383 20 8.97577V9.80209C19.9827 9.8676 19.9693 9.93447 19.96 10.0022C19.8708 11.2186 19.5113 12.3861 18.9177 13.3875C17.961 15.0025 16.6297 16.2594 15.0825 17.0082C12.4657 18.3525 9.75693 18.5667 6.98209 17.8346C6.8589 17.8074 6.73157 17.8264 6.61799 17.8887C5.15955 18.7339 3.70511 19.5908 2.24867 20.4501C2.18866 20.4854 2.12464 20.5183 2.0146 20.5748L3.78714 16.3703C3.37301 16.0148 2.96889 15.7017 2.60078 15.3415C1.42243 14.1879 0.556167 12.7895 0.182055 11.0192C0.0980294 10.6213 0.060018 10.2094 0 9.80209ZM14.0042 10.5931C14.1362 10.5968 14.2676 10.5698 14.3907 10.5135C14.5138 10.4572 14.6262 10.3728 14.7214 10.2651C14.8167 10.1574 14.8928 10.0286 14.9455 9.8861C14.9982 9.7436 15.0264 9.59023 15.0285 9.43484V9.4113C15.0285 9.25517 15.0024 9.10058 14.9516 8.95634C14.9008 8.8121 14.8264 8.68104 14.7326 8.57064C14.6388 8.46025 14.5274 8.37268 14.4048 8.31293C14.2823 8.25319 14.1509 8.22243 14.0182 8.22243C13.8855 8.22243 13.7542 8.25319 13.6316 8.31293C13.509 8.37268 13.3976 8.46025 13.3038 8.57064C13.21 8.68104 13.1356 8.8121 13.0848 8.95634C13.034 9.10058 13.0079 9.25517 13.0079 9.4113C13.0074 9.56588 13.0327 9.71906 13.0825 9.86211C13.1323 10.0052 13.2055 10.1353 13.2981 10.245C13.3906 10.3547 13.5005 10.442 13.6217 10.5017C13.7429 10.5614 13.8728 10.5925 14.0042 10.5931ZM10.003 10.5931C10.203 10.5926 10.3983 10.5225 10.5644 10.3915C10.7306 10.2606 10.86 10.0746 10.9364 9.85719C11.0129 9.63976 11.0329 9.40056 10.9939 9.16977C10.9549 8.93898 10.8588 8.72694 10.7175 8.5604C10.5763 8.39385 10.3962 8.28026 10.2002 8.23396C10.0041 8.18765 9.80084 8.21071 9.61591 8.30022C9.43099 8.38973 9.27273 8.54168 9.1611 8.7369C9.04948 8.93212 8.98949 9.16187 8.9887 9.39717C8.98975 9.71356 9.09688 10.0167 9.28682 10.2406C9.47675 10.4646 9.73413 10.5912 10.003 10.5931ZM4.98349 9.3854C4.9836 9.61979 5.04316 9.8488 5.15456 10.0431C5.26595 10.2374 5.42411 10.3882 5.60876 10.476C5.79341 10.5639 5.99616 10.5849 6.19102 10.5364C6.38588 10.4878 6.56399 10.3719 6.70252 10.2035C6.84105 10.0351 6.93371 9.82183 6.96861 9.59108C7.00352 9.36032 6.97909 9.12255 6.89845 8.90823C6.8178 8.69392 6.68463 8.51281 6.51597 8.38811C6.34732 8.26342 6.15087 8.20081 5.95179 8.20831C5.69208 8.21809 5.44579 8.34641 5.26507 8.56611C5.08434 8.78581 4.98336 9.07963 4.98349 9.3854Z"
|
||||
fill={color}
|
||||
/>
|
||||
</SvgContainer>
|
||||
);
|
||||
};
|