From 4fef5ec4c41ae4625351fcd0f3b67e8de3055d42 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 16:36:01 +0000 Subject: [PATCH] refactor: Remove config, display, and i18n packages Removes the following unused packages: - pkg/config - pkg/display - pkg/i18n Also removes the dependencies from pkg/runtime and cleans up the go.mod and go.sum files. --- go.mod | 5 +- go.sum | 4 - pkg/config/config.go | 22 - pkg/config/config_test.go | 206 - pkg/config/internal/config_test.go | 184 - pkg/config/internal/service.go | 207 - pkg/display/actions.go | 8 - pkg/display/display.go | 159 - pkg/display/display_test.go | 44 - pkg/display/menu.go | 32 - pkg/display/tray.go | 72 - pkg/display/window.go | 93 - pkg/i18n/editor.babel | 5685 ---------------------------- pkg/i18n/i18n.go | 187 - pkg/i18n/i18n_test.go | 69 - pkg/i18n/locales/de.json | 157 - pkg/i18n/locales/en.json | 157 - pkg/i18n/locales/es.json | 157 - pkg/i18n/locales/fr.json | 157 - pkg/i18n/locales/ru.json | 157 - pkg/i18n/locales/uk.json | 157 - pkg/i18n/locales/zh.json | 157 - pkg/i18n/testdata/en.json | 3 - pkg/i18n/testdata/es.json | 3 - pkg/runtime/runtime.go | 26 +- pkg/runtime/runtime_test.go | 22 +- 26 files changed, 5 insertions(+), 8125 deletions(-) delete mode 100644 pkg/config/config.go delete mode 100644 pkg/config/config_test.go delete mode 100644 pkg/config/internal/config_test.go delete mode 100644 pkg/config/internal/service.go delete mode 100644 pkg/display/actions.go delete mode 100644 pkg/display/display.go delete mode 100644 pkg/display/display_test.go delete mode 100644 pkg/display/menu.go delete mode 100644 pkg/display/tray.go delete mode 100644 pkg/display/window.go delete mode 100644 pkg/i18n/editor.babel delete mode 100644 pkg/i18n/i18n.go delete mode 100644 pkg/i18n/i18n_test.go delete mode 100644 pkg/i18n/locales/de.json delete mode 100644 pkg/i18n/locales/en.json delete mode 100644 pkg/i18n/locales/es.json delete mode 100644 pkg/i18n/locales/fr.json delete mode 100644 pkg/i18n/locales/ru.json delete mode 100644 pkg/i18n/locales/uk.json delete mode 100644 pkg/i18n/locales/zh.json delete mode 100644 pkg/i18n/testdata/en.json delete mode 100644 pkg/i18n/testdata/es.json diff --git a/go.mod b/go.mod index 95fda7a..99715f1 100644 --- a/go.mod +++ b/go.mod @@ -4,19 +4,17 @@ go 1.25 require ( github.com/ProtonMail/go-crypto v1.3.0 - github.com/adrg/xdg v0.5.3 - github.com/nicksnyder/go-i18n/v2 v2.6.0 github.com/pkg/sftp v1.13.10 github.com/skeema/knownhosts v1.3.2 github.com/stretchr/testify v1.11.1 github.com/wailsapp/wails/v3 v3.0.0-alpha.37 golang.org/x/crypto v0.43.0 - golang.org/x/text v0.30.0 ) require ( dario.cat/mergo v1.0.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/adrg/xdg v0.5.3 // indirect github.com/bep/debounce v1.2.1 // indirect github.com/cloudflare/circl v1.6.1 // indirect github.com/cyphar/filepath-securejoin v0.5.1 // indirect @@ -52,6 +50,7 @@ require ( github.com/xanzy/ssh-agent v0.3.3 // indirect golang.org/x/net v0.46.0 // indirect golang.org/x/sys v0.37.0 // indirect + golang.org/x/text v0.30.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 3d3b5ef..1790463 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= -github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= -github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= @@ -78,8 +76,6 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/nicksnyder/go-i18n/v2 v2.6.0 h1:C/m2NNWNiTB6SK4Ao8df5EWm3JETSTIGNXBpMJTxzxQ= -github.com/nicksnyder/go-i18n/v2 v2.6.0/go.mod h1:88sRqr0C6OPyJn0/KRNaEz1uWorjxIKP7rUUcvycecE= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0= diff --git a/pkg/config/config.go b/pkg/config/config.go deleted file mode 100644 index ee27ed1..0000000 --- a/pkg/config/config.go +++ /dev/null @@ -1,22 +0,0 @@ -package config - -import ( - "github.com/Snider/Core/pkg/config/internal" - "github.com/Snider/Core/pkg/core" -) - -// Options holds configuration for the config service. -type Options = internal.Options - -// Service provides access to the application's configuration. -type Service = internal.Service - -// New is the constructor for static dependency injection. -func New() (*Service, error) { - return internal.New() -} - -// Register is the constructor for dynamic dependency injection. -func Register(c *core.Core) (any, error) { - return internal.Register(c) -} diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go deleted file mode 100644 index 54b98c3..0000000 --- a/pkg/config/config_test.go +++ /dev/null @@ -1,206 +0,0 @@ -package config - -import ( - "os" - "path/filepath" - "testing" - - "github.com/Snider/Core/pkg/core" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -const appName = "lethean" -const configFileName = "config.json" - -// setupTestEnv creates a temporary home directory for testing and ensures a clean environment. -func setupTestEnv(t *testing.T) (string, func()) { - tempHomeDir, err := os.MkdirTemp("", "test_home_*") - require.NoError(t, err, "Failed to create temp home directory") - - oldHome := os.Getenv("HOME") - os.Setenv("HOME", tempHomeDir) - - // Unset XDG vars to ensure HOME is used for path resolution, creating a hermetic test. - oldXdgData, hadXdgData := os.LookupEnv("XDG_DATA_HOME") - oldXdgCache, hadXdgCache := os.LookupEnv("XDG_CACHE_HOME") - require.NoError(t, os.Unsetenv("XDG_DATA_HOME")) - require.NoError(t, os.Unsetenv("XDG_CACHE_HOME")) - - cleanup := func() { - os.Setenv("HOME", oldHome) - if hadXdgData { - os.Setenv("XDG_DATA_HOME", oldXdgData) - } else { - os.Unsetenv("XDG_DATA_HOME") - } - if hadXdgCache { - os.Setenv("XDG_CACHE_HOME", oldXdgCache) - } else { - os.Unsetenv("XDG_CACHE_HOME") - } - os.RemoveAll(tempHomeDir) - } - - return tempHomeDir, cleanup -} - -func TestConfigService(t *testing.T) { - t.Run("New service creates default config", func(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - serviceInstance, err := New() - require.NoError(t, err, "New() failed") - - // Check that the config file was created - assert.FileExists(t, serviceInstance.ConfigPath, "config.json was not created") - - // Check default values - assert.Equal(t, "en", serviceInstance.Language, "Expected default language 'en'") - }) - - t.Run("New service loads existing config", func(t *testing.T) { - tempHomeDir, cleanup := setupTestEnv(t) - defer cleanup() - - // Manually create a config file with non-default values - configDir := filepath.Join(tempHomeDir, appName, "config") - require.NoError(t, os.MkdirAll(configDir, os.ModePerm), "Failed to create test config dir") - configPath := filepath.Join(configDir, configFileName) - - customConfig := `{"language": "fr", "features": ["beta-testing"]}` - require.NoError(t, os.WriteFile(configPath, []byte(customConfig), 0644), "Failed to write custom config file") - - serviceInstance, err := New() - require.NoError(t, err, "New() failed while loading existing config") - - assert.Equal(t, "fr", serviceInstance.Language, "Expected language 'fr'") - assert.True(t, serviceInstance.IsFeatureEnabled("beta-testing"), "Expected 'beta-testing' feature to be enabled") - assert.False(t, serviceInstance.IsFeatureEnabled("alpha-testing"), "Did not expect 'alpha-testing' to be enabled") - }) - - t.Run("Set and Get", func(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - s, err := New() - require.NoError(t, err, "New() failed") - - key := "language" - expectedValue := "de" - require.NoError(t, s.Set(key, expectedValue), "Set() failed") - - var actualValue string - require.NoError(t, s.Get(key, &actualValue), "Get() failed") - assert.Equal(t, expectedValue, actualValue, "Get() returned unexpected value") - }) -} - -func TestIsFeatureEnabled(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - s, err := New() - require.NoError(t, err) - - // Test with no features enabled - assert.False(t, s.IsFeatureEnabled("beta-feature")) - - // Enable a feature - err = s.Set("features", []string{"beta-feature", "alpha-testing"}) - require.NoError(t, err) - - // Test for an enabled feature - assert.True(t, s.IsFeatureEnabled("beta-feature")) - - // Test for another enabled feature - assert.True(t, s.IsFeatureEnabled("alpha-testing")) - - // Test for a disabled feature - assert.False(t, s.IsFeatureEnabled("gamma-feature")) - - // Test with an empty string - assert.False(t, s.IsFeatureEnabled("")) -} - -func TestSet_Good(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - s, err := New() - require.NoError(t, err, "New() failed") - - // Test setting a string value - err = s.Set("language", "de") - assert.NoError(t, err) - var lang string - err = s.Get("language", &lang) - assert.NoError(t, err) - assert.Equal(t, "de", lang) - - // Test setting a slice value - err = s.Set("features", []string{"new-feature"}) - assert.NoError(t, err) - var features []string - err = s.Get("features", &features) - assert.NoError(t, err) - assert.Equal(t, []string{"new-feature"}, features) -} - -func TestSet_Bad(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - s, err := New() - require.NoError(t, err, "New() failed") - - // Test setting a value with the wrong type - err = s.Set("language", 123) - assert.Error(t, err) - - // Test setting a non-existent key - err = s.Set("nonExistentKey", "value") - assert.Error(t, err) -} - -func TestSet_Ugly(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - s, err := New() - require.NoError(t, err, "New() failed") - - // This should not panic - assert.NotPanics(t, func() { - err = s.Set("features", nil) - }) - assert.NoError(t, err) - - // Verify the slice is now nil - var features []string - err = s.Get("features", &features) - assert.NoError(t, err) - assert.Nil(t, features) - - // Test with a nil slice - err = s.Set("features", nil) - require.NoError(t, err) - assert.False(t, s.IsFeatureEnabled("beta-feature")) -} - -func TestRegister_Good(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - c, err := core.New() - require.NoError(t, err) - - svc, err := Register(c) - assert.NoError(t, err) - assert.NotNil(t, svc) - - configSvc, ok := svc.(*Service) - assert.True(t, ok) - assert.NotNil(t, configSvc.Runtime) -} diff --git a/pkg/config/internal/config_test.go b/pkg/config/internal/config_test.go deleted file mode 100644 index 71e00d4..0000000 --- a/pkg/config/internal/config_test.go +++ /dev/null @@ -1,184 +0,0 @@ -package internal - -import ( - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -// setupTestEnv creates a temporary home directory for testing and ensures a clean environment. -func setupTestEnv(t *testing.T) (string, func()) { - tempHomeDir, err := os.MkdirTemp("", "test_home_*") - require.NoError(t, err, "Failed to create temp home directory") - - oldHome := os.Getenv("HOME") - os.Setenv("HOME", tempHomeDir) - - // Unset XDG vars to ensure HOME is used for path resolution, creating a hermetic test. - oldXdgData, hadXdgData := os.LookupEnv("XDG_DATA_HOME") - oldXdgCache, hadXdgCache := os.LookupEnv("XDG_CACHE_HOME") - require.NoError(t, os.Unsetenv("XDG_DATA_HOME")) - require.NoError(t, os.Unsetenv("XDG_CACHE_HOME")) - - cleanup := func() { - os.Setenv("HOME", oldHome) - if hadXdgData { - os.Setenv("XDG_DATA_HOME", oldXdgData) - } else { - os.Unsetenv("XDG_DATA_HOME") - } - if hadXdgCache { - os.Setenv("XDG_CACHE_HOME", oldXdgCache) - } else { - os.Unsetenv("XDG_CACHE_HOME") - } - os.RemoveAll(tempHomeDir) - } - - return tempHomeDir, cleanup -} - -func TestConfigService(t *testing.T) { - t.Run("New service creates default config", func(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - serviceInstance, err := New() - require.NoError(t, err, "New() failed") - - // Check that the config file was created - assert.FileExists(t, serviceInstance.ConfigPath, "config.json was not created") - - // Check default values - assert.Equal(t, "en", serviceInstance.Language, "Expected default language 'en'") - }) - - t.Run("New service loads existing config", func(t *testing.T) { - tempHomeDir, cleanup := setupTestEnv(t) - defer cleanup() - - // Manually create a config file with non-default values - configDir := filepath.Join(tempHomeDir, appName, "config") - require.NoError(t, os.MkdirAll(configDir, os.ModePerm), "Failed to create test config dir") - configPath := filepath.Join(configDir, configFileName) - - customConfig := `{"language": "fr", "features": ["beta-testing"]}` - require.NoError(t, os.WriteFile(configPath, []byte(customConfig), 0644), "Failed to write custom config file") - - serviceInstance, err := New() - require.NoError(t, err, "New() failed while loading existing config") - - assert.Equal(t, "fr", serviceInstance.Language, "Expected language 'fr'") - assert.True(t, serviceInstance.IsFeatureEnabled("beta-testing"), "Expected 'beta-testing' feature to be enabled") - assert.False(t, serviceInstance.IsFeatureEnabled("alpha-testing"), "Did not expect 'alpha-testing' to be enabled") - }) - - t.Run("Set and Get", func(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - s, err := New() - require.NoError(t, err, "New() failed") - - key := "language" - expectedValue := "de" - require.NoError(t, s.Set(key, expectedValue), "Set() failed") - - var actualValue string - require.NoError(t, s.Get(key, &actualValue), "Get() failed") - assert.Equal(t, expectedValue, actualValue, "Get() returned unexpected value") - }) -} - -func TestIsFeatureEnabled(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - s, err := New() - require.NoError(t, err) - - // Test with no features enabled - assert.False(t, s.IsFeatureEnabled("beta-feature")) - - // Enable a feature - s.Features = []string{"beta-feature", "alpha-testing"} - - // Test for an enabled feature - assert.True(t, s.IsFeatureEnabled("beta-feature")) - - // Test for another enabled feature - assert.True(t, s.IsFeatureEnabled("alpha-testing")) - - // Test for a disabled feature - assert.False(t, s.IsFeatureEnabled("gamma-feature")) - - // Test with an empty string - assert.False(t, s.IsFeatureEnabled("")) - - // Test with a nil slice - s.Features = nil - assert.False(t, s.IsFeatureEnabled("beta-feature")) -} - -func TestSet_Good(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - s, err := New() - require.NoError(t, err, "New() failed") - - // Test setting a string value - err = s.Set("language", "de") - assert.NoError(t, err) - var lang string - err = s.Get("language", &lang) - assert.NoError(t, err) - assert.Equal(t, "de", lang) - - // Test setting a slice value - err = s.Set("features", []string{"new-feature"}) - assert.NoError(t, err) - var features []string - err = s.Get("features", &features) - assert.NoError(t, err) - assert.Equal(t, []string{"new-feature"}, features) -} - -func TestSet_Bad(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - s, err := New() - require.NoError(t, err, "New() failed") - - // Test setting a value with the wrong type - err = s.Set("language", 123) - assert.Error(t, err) - - // Test setting a non-existent key - err = s.Set("nonExistentKey", "value") - assert.Error(t, err) -} - -func TestSet_Ugly(t *testing.T) { - _, cleanup := setupTestEnv(t) - defer cleanup() - - s, err := New() - require.NoError(t, err, "New() failed") - - // This should not panic - assert.NotPanics(t, func() { - err = s.Set("features", nil) - }) - assert.NoError(t, err) - - // Verify the slice is now nil - var features []string - err = s.Get("features", &features) - assert.NoError(t, err) - assert.Nil(t, features) -} diff --git a/pkg/config/internal/service.go b/pkg/config/internal/service.go deleted file mode 100644 index ed5964a..0000000 --- a/pkg/config/internal/service.go +++ /dev/null @@ -1,207 +0,0 @@ -package internal - -import ( - "encoding/json" - "errors" - "fmt" - "os" - "path/filepath" - "reflect" - "strings" - - "github.com/Snider/Core/pkg/core" - "github.com/adrg/xdg" -) - -const appName = "lethean" -const configFileName = "config.json" - -// Options holds configuration for the config service. -type Options struct{} - -// Service provides access to the application's configuration. -// It handles loading, saving, and providing access to configuration values. -type Service struct { - *core.Runtime[Options] `json:"-"` - - // Persistent fields, saved to config.json. - ConfigPath string `json:"configPath,omitempty"` - UserHomeDir string `json:"userHomeDir,omitempty"` - RootDir string `json:"rootDir,omitempty"` - CacheDir string `json:"cacheDir,omitempty"` - ConfigDir string `json:"configDir,omitempty"` - DataDir string `json:"dataDir,omitempty"` - WorkspaceDir string `json:"workspaceDir,omitempty"` - DefaultRoute string `json:"default_route"` - Features []string `json:"features"` - Language string `json:"language"` -} - -// createServiceInstance contains the common logic for initializing a Service struct. -func createServiceInstance() (*Service, error) { - // --- Path and Directory Setup --- - homeDir, err := os.UserHomeDir() - if err != nil { - return nil, fmt.Errorf("could not resolve user home directory: %w", err) - } - userHomeDir := filepath.Join(homeDir, appName) - - rootDir, err := xdg.DataFile(appName) - if err != nil { - return nil, fmt.Errorf("could not resolve data directory: %w", err) - } - - cacheDir, err := xdg.CacheFile(appName) - if err != nil { - return nil, fmt.Errorf("could not resolve cache directory: %w", err) - } - - s := &Service{ - UserHomeDir: userHomeDir, - RootDir: rootDir, - CacheDir: cacheDir, - ConfigDir: filepath.Join(userHomeDir, "config"), - DataDir: filepath.Join(userHomeDir, "data"), - WorkspaceDir: filepath.Join(userHomeDir, "workspace"), - DefaultRoute: "/", - Features: []string{}, - Language: "en", - } - s.ConfigPath = filepath.Join(s.ConfigDir, configFileName) - - dirs := []string{s.RootDir, s.ConfigDir, s.DataDir, s.CacheDir, s.WorkspaceDir, s.UserHomeDir} - for _, dir := range dirs { - if err := os.MkdirAll(dir, os.ModePerm); err != nil { - return nil, fmt.Errorf("could not create directory %s: %w", dir, err) - } - } - - // --- Load or Create Configuration --- - if data, err := os.ReadFile(s.ConfigPath); err == nil { - // Config file exists, load it. - if err := json.Unmarshal(data, s); err != nil { - return nil, fmt.Errorf("failed to unmarshal config: %w", err) - } - } else if os.IsNotExist(err) { - // Config file does not exist, create it with default values. - if err := s.Save(); err != nil { - return nil, fmt.Errorf("failed to create default config file: %w", err) - } - } else { - // Another error occurred reading the file. - return nil, fmt.Errorf("failed to read config file: %w", err) - } - - return s, nil -} - -// New is the constructor for static dependency injection. -// It creates a Service instance without initializing the core.Runtime field. -func New() (*Service, error) { - return createServiceInstance() -} - -// Register is the constructor for dynamic dependency injection (used with core.WithService). -// It creates a Service instance and initializes its core.Runtime field. -func Register(c *core.Core) (any, error) { - s, err := createServiceInstance() - if err != nil { - return nil, err - } - // Defensive check: createServiceInstance should not return nil service with nil error - if s == nil { - return nil, errors.New("config: createServiceInstance returned a nil service instance with no error") - } - s.Runtime = core.NewRuntime(c, Options{}) - return s, nil -} - -// Save writes the current configuration to config.json. -func (s *Service) Save() error { - data, err := json.MarshalIndent(s, "", " ") - if err != nil { - return fmt.Errorf("failed to marshal config: %w", err) - } - - if err := os.WriteFile(s.ConfigPath, data, 0644); err != nil { - return fmt.Errorf("failed to write config file: %w", err) - } - return nil -} - -// Get retrieves a configuration value by its key. -func (s *Service) Get(key string, out any) error { - val := reflect.ValueOf(s).Elem() - typ := val.Type() - - for i := 0; i < val.NumField(); i++ { - field := typ.Field(i) - jsonTag := field.Tag.Get("json") - if jsonTag != "" && jsonTag != "-" { - jsonName := strings.Split(jsonTag, ",")[0] - if strings.EqualFold(jsonName, key) { - outVal := reflect.ValueOf(out) - if outVal.Kind() != reflect.Ptr || outVal.IsNil() { - return errors.New("output argument must be a non-nil pointer") - } - targetVal := outVal.Elem() - srcVal := val.Field(i) - - if !srcVal.Type().AssignableTo(targetVal.Type()) { - return fmt.Errorf("cannot assign config value of type %s to output of type %s", srcVal.Type(), targetVal.Type()) - } - targetVal.Set(srcVal) - return nil - } - } - } - - return fmt.Errorf("key '%s' not found in config", key) -} - -// IsFeatureEnabled checks if a specific feature is enabled in the config. -func (s *Service) IsFeatureEnabled(feature string) bool { - for _, f := range s.Features { - if f == feature { - return true - } - } - return false -} - -// Set updates a configuration value and saves the config. -func (s *Service) Set(key string, v any) error { - val := reflect.ValueOf(s).Elem() - typ := val.Type() - - for i := 0; i < val.NumField(); i++ { - field := typ.Field(i) - jsonTag := field.Tag.Get("json") - if jsonTag != "" && jsonTag != "-" { - jsonName := strings.Split(jsonTag, ",")[0] - if strings.EqualFold(jsonName, key) { - fieldVal := val.Field(i) - if !fieldVal.CanSet() { - return fmt.Errorf("cannot set config field for key '%s'", key) - } - if v == nil { - switch fieldVal.Kind() { - case reflect.Pointer, reflect.Interface, reflect.Map, reflect.Slice, reflect.Func: - fieldVal.Set(reflect.Zero(fieldVal.Type())) - return s.Save() - default: - return fmt.Errorf("type mismatch for key '%s': expected %s, got nil", key, fieldVal.Type()) - } - } - newVal := reflect.ValueOf(v) - if !newVal.Type().AssignableTo(fieldVal.Type()) { - return fmt.Errorf("type mismatch for key '%s': expected %s, got %s", key, fieldVal.Type(), newVal.Type()) - } - fieldVal.Set(newVal) - return s.Save() - } - } - } - - return fmt.Errorf("key '%s' not found in config", key) -} diff --git a/pkg/display/actions.go b/pkg/display/actions.go deleted file mode 100644 index ba2d8fd..0000000 --- a/pkg/display/actions.go +++ /dev/null @@ -1,8 +0,0 @@ -package display - -import "github.com/wailsapp/wails/v3/pkg/application" - -// ActionOpenWindow is an IPC message used to request a new window. -type ActionOpenWindow struct { - application.WebviewWindowOptions -} diff --git a/pkg/display/display.go b/pkg/display/display.go deleted file mode 100644 index 843e5f6..0000000 --- a/pkg/display/display.go +++ /dev/null @@ -1,159 +0,0 @@ -package display - -import ( - "context" - "fmt" - - "github.com/Snider/Core/pkg/core" - "github.com/wailsapp/wails/v3/pkg/application" - "github.com/wailsapp/wails/v3/pkg/events" -) - -// Options holds configuration for the display service. -type Options struct{} - -// Service manages windowing, dialogs, and other visual elements. -type Service struct { - *core.Runtime[Options] - config core.Config -} - -// newDisplayService contains the common logic for initializing a Service struct. -func newDisplayService() (*Service, error) { - return &Service{}, nil -} - -// New is the constructor for static dependency injection. -// It creates a Service instance without initializing the core.Runtime field. -func New() (*Service, error) { - s, err := newDisplayService() - if err != nil { - return nil, err - } - return s, nil -} - -// Register is the constructor for dynamic dependency injection (used with core.WithService). -// It creates a Service instance and initializes its core.Runtime field. -func Register(c *core.Core) (any, error) { - s, err := newDisplayService() - if err != nil { - return nil, err - } - s.Runtime = core.NewRuntime(c, Options{}) - return s, nil -} - -func (s *Service) ServiceName() string { return "github.com/Snider/Core/display" } - -// HandleIPCEvents processes IPC messages and performs actions such as opening windows or initializing services based on message types. -func (s *Service) HandleIPCEvents(c *core.Core, msg core.Message) error { - switch m := msg.(type) { - case map[string]any: - if action, ok := m["action"].(string); ok && action == "display.open_window" { - return s.handleOpenWindowAction(m) - } - case ActionOpenWindow: - _, err := s.NewWithStruct(&m.WebviewWindowOptions) - return err - case core.ActionServiceStartup: - return s.ServiceStartup(context.Background(), application.ServiceOptions{}) - default: - c.App.Logger.Error("Display: Unknown message type", "type", fmt.Sprintf("%T", m)) - } - return nil -} - -// handleOpenWindowAction processes a message to configure and create a new window using specified name and options. -func (s *Service) handleOpenWindowAction(msg map[string]any) error { - opts := application.WebviewWindowOptions{} - if name, ok := msg["name"].(string); ok { - opts.Name = name - } - if optsMap, ok := msg["options"].(map[string]any); ok { - if title, ok := optsMap["Title"].(string); ok { - opts.Title = title - } - if width, ok := optsMap["Width"].(float64); ok { - opts.Width = int(width) - } - if height, ok := optsMap["Height"].(float64); ok { - opts.Height = int(height) - } - } - s.Core().App.Window.NewWithOptions(opts) - return nil -} - -// ShowEnvironmentDialog displays a dialog containing detailed information about the application's runtime environment. -func (s *Service) ShowEnvironmentDialog() { - envInfo := s.Core().App.Env.Info() - - details := fmt.Sprintf(`Environment Information:\n\nOperating System: %s\nArchitecture: %s\nDebug Mode: %t\n\nDark Mode: %t\n\nPlatform Information:`, - envInfo.OS, - envInfo.Arch, - envInfo.Debug, - s.Core().App.Env.IsDarkMode()) // Use d.core.App - - // Add platform-specific details - for key, value := range envInfo.PlatformInfo { - details += fmt.Sprintf("\n%s: %v", key, value) - } - - if envInfo.OSInfo != nil { - details += fmt.Sprintf("\n\nOS Details:\nName: %s\nVersion: %s", - envInfo.OSInfo.Name, - envInfo.OSInfo.Version) - } - - dialog := s.Core().App.Dialog.Info() - dialog.SetTitle("Environment Information") - dialog.SetMessage(details) - dialog.Show() -} - -// ServiceStartup initializes the display service and sets up the main application window and system tray. -func (s *Service) ServiceStartup(context.Context, application.ServiceOptions) error { - s.Core().App.Logger.Info("Display service started") - s.buildMenu() - s.systemTray() - - // This will be updated to use the restored OpenWindow method - return s.OpenWindow() -} - -// OpenWindow creates a new window with the default options. -func (s *Service) OpenWindow(opts ...core.WindowOption) error { - // Default options - winOpts := &core.WindowConfig{ - Name: "main", - Title: "Core", - Width: 1280, - Height: 800, - URL: "/", - } - - // Apply options - for _, opt := range opts { - opt.Apply(winOpts) - } - - // Create Wails window options - wailsOpts := application.WebviewWindowOptions{ - Name: winOpts.Name, - Title: winOpts.Title, - Width: winOpts.Width, - Height: winOpts.Height, - URL: winOpts.URL, - } - - s.Core().App.Window.NewWithOptions(wailsOpts) - return nil -} - -// monitorScreenChanges listens for theme change events and logs when screen configuration changes occur. -func (s *Service) monitorScreenChanges() { - s.Core().App.Event.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) { - s.Core().App.Logger.Info("Screen configuration changed") - }) -} diff --git a/pkg/display/display_test.go b/pkg/display/display_test.go deleted file mode 100644 index 9f135f0..0000000 --- a/pkg/display/display_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package display - -import ( - "testing" - - "github.com/Snider/Core/pkg/core" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -// newTestCore creates a new core instance with essential services for testing. -func newTestCore(t *testing.T) *core.Core { - // We need a real wails app for the display service to function. - // This setup will be more complex than for other services. - // For now, we can use a simplified core instance. - coreInstance, err := core.New() - require.NoError(t, err) - return coreInstance -} - -func TestNew(t *testing.T) { - service, err := New() - assert.NoError(t, err) - assert.NotNil(t, service, "New() should return a non-nil service instance") -} - -func TestRegister(t *testing.T) { - coreInstance := newTestCore(t) - service, err := Register(coreInstance) - require.NoError(t, err) - assert.NotNil(t, service, "Register() should return a non-nil service instance") -} - -func TestOpenWindow(t *testing.T) { - // This test is complex to set up properly without a running Wails application. - // A true functional test would require a more elaborate test harness that - // can initialize the Wails runtime. - - // For now, we can perform a basic smoke test. - t.Run("basic window open smoke test", func(t *testing.T) { - // Skipping this test for now as it requires a running app instance. - t.Skip("Skipping OpenWindow test as it requires a running Wails application instance.") - }) -} diff --git a/pkg/display/menu.go b/pkg/display/menu.go deleted file mode 100644 index 63bb0d1..0000000 --- a/pkg/display/menu.go +++ /dev/null @@ -1,32 +0,0 @@ -package display - -import ( - "runtime" - - "github.com/wailsapp/wails/v3/pkg/application" -) - -// buildMenu creates and sets the main application menu. -func (s *Service) buildMenu() { - appMenu := s.Core().App.Menu.New() - if runtime.GOOS == "darwin" { - appMenu.AddRole(application.AppMenu) - } - appMenu.AddRole(application.FileMenu) - appMenu.AddRole(application.ViewMenu) - appMenu.AddRole(application.EditMenu) - - workspace := appMenu.AddSubmenu("Workspace") - workspace.Add("New").OnClick(func(ctx *application.Context) { /* TODO */ }) - workspace.Add("List").OnClick(func(ctx *application.Context) { /* TODO */ }) - - // Add brand-specific menu items - //if s.brand == DeveloperHub { - // appMenu.AddSubmenu("Developer") - //} - - appMenu.AddRole(application.WindowMenu) - appMenu.AddRole(application.HelpMenu) - - s.Core().App.Menu.Set(appMenu) -} diff --git a/pkg/display/tray.go b/pkg/display/tray.go deleted file mode 100644 index b96f2ef..0000000 --- a/pkg/display/tray.go +++ /dev/null @@ -1,72 +0,0 @@ -package display - -import ( - _ "embed" - - "github.com/wailsapp/wails/v3/pkg/application" -) - -// setupTray configures and creates the system tray icon and menu. -func (s *Service) systemTray() { - - systray := s.Core().App.SystemTray.New() - systray.SetTooltip("Core") - systray.SetLabel("Core") - //appTrayIcon, _ := d.assets.ReadFile("assets/apptray.png") - // - //if runtime.GOOS == "darwin" { - // systray.SetTemplateIcon(appTrayIcon) - //} else { - // // Support for light/dark mode icons - // systray.SetDarkModeIcon(appTrayIcon) - // systray.SetIcon(appTrayIcon) - //} - // Create a hidden window for the system tray menu to interact with - trayWindow, _ := s.NewWithStruct(&Window{ - Name: "system-tray", - Title: "System Tray Status", - URL: "system-tray.html", - Width: 400, - Frameless: true, - Hidden: true, - }) - systray.AttachWindow(trayWindow).WindowOffset(5) - - // --- Build Tray Menu --- - trayMenu := s.Core().App.Menu.New() - trayMenu.Add("Open Desktop").OnClick(func(ctx *application.Context) { - for _, window := range s.Core().App.Window.GetAll() { - window.Show() - } - }) - trayMenu.Add("Close Desktop").OnClick(func(ctx *application.Context) { - for _, window := range s.Core().App.Window.GetAll() { - window.Hide() - } - }) - - trayMenu.Add("Environment Info").OnClick(func(ctx *application.Context) { - s.ShowEnvironmentDialog() - }) - // Add brand-specific menu items - //switch d.brand { - //case AdminHub: - // trayMenu.Add("Manage Workspace").OnClick(func(ctx *application.Context) { /* TODO */ }) - //case ServerHub: - // trayMenu.Add("Server Control").OnClick(func(ctx *application.Context) { /* TODO */ }) - //case GatewayHub: - // trayMenu.Add("Routing Table").OnClick(func(ctx *application.Context) { /* TODO */ }) - //case DeveloperHub: - // trayMenu.Add("Debug Console").OnClick(func(ctx *application.Context) { /* TODO */ }) - //case ClientHub: - // trayMenu.Add("Connect").OnClick(func(ctx *application.Context) { /* TODO */ }) - // trayMenu.Add("Disconnect").OnClick(func(ctx *application.Context) { /* TODO */ }) - //} - - trayMenu.AddSeparator() - trayMenu.Add("Quit").OnClick(func(ctx *application.Context) { - s.Core().App.Quit() - }) - - systray.SetMenu(trayMenu) -} diff --git a/pkg/display/window.go b/pkg/display/window.go deleted file mode 100644 index 6dc0a8a..0000000 --- a/pkg/display/window.go +++ /dev/null @@ -1,93 +0,0 @@ -package display - -import ( - "github.com/wailsapp/wails/v3/pkg/application" -) - -type WindowOption func(*application.WebviewWindowOptions) error - -type Window = application.WebviewWindowOptions - -func WindowName(s string) WindowOption { - return func(o *Window) error { - o.Name = s - return nil - } -} -func WindowTitle(s string) WindowOption { - return func(o *Window) error { - o.Title = s - return nil - } -} - -func WindowURL(s string) WindowOption { - return func(o *Window) error { - o.URL = s - return nil - } -} - -func WindowWidth(i int) WindowOption { - return func(o *Window) error { - o.Width = i - return nil - } -} - -func WindowHeight(i int) WindowOption { - return func(o *Window) error { - o.Height = i - return nil - } -} - -func applyOptions(opts ...WindowOption) *Window { - w := &Window{} - if opts == nil { - return w - } - for _, o := range opts { - if err := o(w); err != nil { - return nil - } - } - return w -} - -// NewWithStruct creates a new window using the provided options and returns its handle. -func (s *Service) NewWithStruct(options *Window) (*application.WebviewWindow, error) { - return s.Core().App.Window.NewWithOptions(*options), nil -} - -// NewWithOptions creates a new window by applying a series of options. -func (s *Service) NewWithOptions(opts ...WindowOption) (*application.WebviewWindow, error) { - return s.NewWithStruct(applyOptions(opts...)) -} - -// NewWithURL creates a new default window pointing to the specified URL. -func (s *Service) NewWithURL(url string) (*application.WebviewWindow, error) { - return s.NewWithOptions( - WindowURL(url), - WindowTitle("Core"), - WindowHeight(900), - WindowWidth(1280), - ) -} - -//// OpenWindow is a convenience method that creates and shows a window from a set of options. -//func (s *Service) OpenWindow(opts ...WindowOption) error { -// _, err := s.NewWithOptions(opts...) -// return err -//} - -// SelectDirectory opens a directory selection dialog and returns the selected path. -func (s *Service) SelectDirectory() (string, error) { - dialog := application.OpenFileDialog() - dialog.SetTitle("Select Project Directory") - return dialog.PromptForSingleSelection() -} - -var instance *Window - -func (s *Service) Window() *Window { return instance } diff --git a/pkg/i18n/editor.babel b/pkg/i18n/editor.babel deleted file mode 100644 index 0fb546c..0000000 --- a/pkg/i18n/editor.babel +++ /dev/null @@ -1,5685 +0,0 @@ - - - - - ngx-translate - editor.babel - - - - - - main - - - app - - - boot - - - download-check - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - folder-check - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - loaded-runtime - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - server-check - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - start-runtime - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - core - - - ui - - - search - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - - - lthn - - - chain - - - daemons - - - lethean-blockchain-export - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - lethean-blockchain-import - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - lethean-wallet-cli - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - lethean-wallet-rpc - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - lethean-wallet-vpn-rpc - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - letheand - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - desc - - - no_transactions - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - description - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - heading - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - menu - - - blocks - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - configuration - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - raw_data - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - stats - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - table - - - age - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - depth - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - difficulty - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - height - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - reward - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - time - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - title - - - chain-status - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - recent-blocks - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - - - title - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - words - - - alt_blocks_count - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - block_size - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - block_size_limit - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - chain_stat - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - chain_stat_value - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - cumulative_difficulty - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - depth - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - difficulty - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - grey_peerlist_size - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - hash - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - height - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - incoming_connections_count - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - install-blockchain - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - last_block_time - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - loading-data - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - major_version - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - miner_transaction - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - miner_tx - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - minor_version - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - nonce - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - orphan_status - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - outgoing_connections_count - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - reward - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - start_time - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - status - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - target - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - target_height - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - testnet - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - timestamp - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - top_height - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - tx_count - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - tx_pool_size - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - unlock_time - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - valid - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - version - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - white_peerlist_size - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - - - console - - - title - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - wallet - - - button - - - create-wallet - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - restore-wallet - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - unlock-wallet - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - label - - - address - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - autosave - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - filename - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - restore-height - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - spend-key - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - view-key - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - wallet-password - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - wallet-password-confirm - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - titles - - - new-wallet - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - restore-keys - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - restore-seed - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - unlock-wallet - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - wallet-transactions - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - - - - - market - - - apps - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - dashboard - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - installed - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - no-apps-installed - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - view-installable-apps - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - title - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - charts - - - network-hashrate - - - subtitle - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - title - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - - - lang - - - de - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - en - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - es - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - fr - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - ru - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - uk - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - zh - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - menu - - - about - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - activity - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - api - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - blockchain - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - build - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - dashboard - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - docs - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - documentation - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - explorer - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - help - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - hub-admin - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - hub-client - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - hub-developer - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - hub-gateway - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - hub-server - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - info - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - logout - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - mining - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - settings - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - vpn - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - wallet - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - your-profile - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - view - - - dashboard - - - description - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - heading - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - title - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - wallets - - - description - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - heading - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - title - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - - - words - - - actions - - - add - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - clone - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - edit - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - install - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - new - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - remove - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - report - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - save - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - states - - - installing - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - installing_desc - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - loading - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - not_installed - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - not_installed_desc - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - things - - - button - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - documentation - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - menu - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - mining-pool - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - page - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - problem - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - type - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - time - - - past - - - day - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - days - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - hour - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - hours - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - minute - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - minutes - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - month - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - months - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - seconds - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - year - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - years - - - - - de-DE - false - - - en-US - false - - - es-ES - false - - - fr-FR - false - - - ru-RU - false - - - uk-UA - false - - - zh-CN - false - - - - - - - - - - - - - - false - false - - - de-DE - - - en-US - - - es-ES - - - fr-FR - - - ru-RU - - - uk-UA - - - zh-CN - - - - - main - - - locales/de.json - de-DE - - - locales/en.json - en-US - - - locales/es.json - es-ES - - - locales/fr.json - fr-FR - - - locales/ru.json - ru-RU - - - locales/uk.json - uk-UA - - - locales/zh.json - zh-CN - - - - - - true - alphabetically - - {{'%1' | translate}} - [translate]="'%1'" - _('%1') - - - - default - - - en-US - - tab - json - true - - diff --git a/pkg/i18n/i18n.go b/pkg/i18n/i18n.go deleted file mode 100644 index a065fe6..0000000 --- a/pkg/i18n/i18n.go +++ /dev/null @@ -1,187 +0,0 @@ -package i18n - -import ( - "context" - "embed" - "encoding/json" - "fmt" - "os" - "strings" - - "github.com/Snider/Core/pkg/core" - "github.com/nicksnyder/go-i18n/v2/i18n" - "github.com/wailsapp/wails/v3/pkg/application" - "golang.org/x/text/language" -) - -//go:embed locales/*.json -var localeFS embed.FS - -// Options holds configuration for the i18n service. -type Options struct{} - -// Service provides internationalization and localization. -type Service struct { - *core.Runtime[Options] - bundle *i18n.Bundle - localizer *i18n.Localizer - availableLangs []language.Tag -} - -// newI18nService contains the common logic for initializing a Service struct. -func newI18nService() (*Service, error) { - bundle := i18n.NewBundle(language.English) - bundle.RegisterUnmarshalFunc("json", json.Unmarshal) - - availableLangs, err := getAvailableLanguages() - if err != nil { - return nil, err - } - - for _, lang := range availableLangs { - filePath := fmt.Sprintf("locales/%s.json", lang.String()) - if _, err := bundle.LoadMessageFileFS(localeFS, filePath); err != nil { - return nil, fmt.Errorf("failed to load message file %s: %w", filePath, err) - } - } - - s := &Service{ - bundle: bundle, - availableLangs: availableLangs, - } - // Language will be set during ServiceStartup after config is available. - return s, nil -} - -// New is the constructor for static dependency injection. -// It creates a Service instance without initializing the core.Runtime field. -// Dependencies are passed directly here. -func New() (*Service, error) { - s, err := newI18nService() - if err != nil { - return nil, err - } - return s, nil -} - -// Register is the constructor for dynamic dependency injection (used with core.WithService). -// It creates a Service instance and initializes its core.Runtime field. -// Dependencies are injected during ServiceStartup. -func Register(c *core.Core) (any, error) { - s, err := newI18nService() - if err != nil { - return nil, err - } - s.Runtime = core.NewRuntime(c, Options{}) - return s, nil -} - -// HandleIPCEvents processes IPC messages, including injecting dependencies on startup. -func (s *Service) HandleIPCEvents(c *core.Core, msg core.Message) error { - switch m := msg.(type) { - case core.ActionServiceStartup: - return s.ServiceStartup(context.Background(), application.ServiceOptions{}) - default: - c.App.Logger.Error("Display: Unknown message type", "type", fmt.Sprintf("%T", m)) - } - return nil -} - -// ServiceStartup is called when the app starts, after dependencies are injected. -func (s *Service) ServiceStartup(context.Context, application.ServiceOptions) error { - // Determine initial language after config is available. - initialLang := "en" - var lang string - _ = s.Config().Get("language", &lang) - if lang != "" { - initialLang = lang - } - err := s.SetLanguage(initialLang) - if err != nil { - return err - } - s.Core().App.Logger.Info("I18n service started") - return nil -} - -// --- Language Management --- - -func getAvailableLanguages() ([]language.Tag, error) { - files, err := localeFS.ReadDir("locales") - if err != nil { - return nil, fmt.Errorf("failed to read embedded locales directory: %w", err) - } - - var availableLangs []language.Tag - for _, file := range files { - lang := strings.TrimSuffix(file.Name(), ".json") - tag := language.Make(lang) - availableLangs = append(availableLangs, tag) - } - return availableLangs, nil -} - -func detectLanguage(supported []language.Tag) (string, error) { - langEnv := os.Getenv("LANG") - if langEnv == "" { - return "", nil - } - - baseLang := strings.Split(langEnv, ".")[0] - parsedLang, err := language.Parse(baseLang) - if err != nil { - return "", fmt.Errorf("failed to parse language tag '%s': %w", baseLang, err) - } - - if len(supported) == 0 { - return "", nil - } - - matcher := language.NewMatcher(supported) - _, index, confidence := matcher.Match(parsedLang) - - if confidence >= language.Low { - return supported[index].String(), nil - } - return "", nil -} - -// --- Public Service Methods --- - -func (s *Service) SetLanguage(lang string) error { - requestedLang, err := language.Parse(lang) - if err != nil { - return fmt.Errorf("i18n: failed to parse language tag \"%s\": %w", lang, err) - } - - if len(s.availableLangs) == 0 { - return fmt.Errorf("i18n: no available languages loaded in the bundle") - } - - matcher := language.NewMatcher(s.availableLangs) - bestMatch, _, confidence := matcher.Match(requestedLang) - - if confidence == language.No { - return fmt.Errorf("i18n: unsupported language: %s", lang) - } - - s.localizer = i18n.NewLocalizer(s.bundle, bestMatch.String()) - return nil -} - -func (s *Service) Translate(messageID string) string { - translation, err := s.localizer.Localize(&i18n.LocalizeConfig{MessageID: messageID}) - if err != nil { - fmt.Fprintf(os.Stderr, "i18n: translation for key \"%s\" not found\n", messageID) - return messageID - } - return translation -} - -// Ensure Service implements the core.I18n interface. -var _ core.I18n = (*Service)(nil) - -// SetBundle is a test helper to inject a bundle. -func (s *Service) SetBundle(bundle *i18n.Bundle) { - s.bundle = bundle -} diff --git a/pkg/i18n/i18n_test.go b/pkg/i18n/i18n_test.go deleted file mode 100644 index 7e58cbd..0000000 --- a/pkg/i18n/i18n_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package i18n - -import ( - "encoding/json" - "testing" - - "github.com/Snider/Core/pkg/core" - "github.com/nicksnyder/go-i18n/v2/i18n" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "golang.org/x/text/language" -) - -func newTestBundle() *i18n.Bundle { - bundle := i18n.NewBundle(language.English) - bundle.RegisterUnmarshalFunc("json", json.Unmarshal) - bundle.MustParseMessageFileBytes([]byte(`{ - "hello": "Hello" - }`), "en.json") - bundle.MustParseMessageFileBytes([]byte(`{ - "hello": "Bonjour" - }`), "fr.json") - return bundle -} - -func TestNew(t *testing.T) { - s, err := New() - assert.NoError(t, err) - assert.NotNil(t, s) -} - -func TestRegister(t *testing.T) { - c, err := core.New() - require.NoError(t, err) - s, err := Register(c) - assert.NoError(t, err) - assert.NotNil(t, s) -} - -func TestSetLanguage(t *testing.T) { - s, err := New() - require.NoError(t, err) - - s.SetBundle(newTestBundle()) - - err = s.SetLanguage("en") - assert.NoError(t, err) - - err = s.SetLanguage("fr") - assert.NoError(t, err) - - err = s.SetLanguage("invalid") - assert.Error(t, err) -} - -func TestTranslate(t *testing.T) { - s, err := New() - require.NoError(t, err) - - s.SetBundle(newTestBundle()) - - err = s.SetLanguage("en") - require.NoError(t, err) - assert.Equal(t, "Hello", s.Translate("hello")) - - err = s.SetLanguage("fr") - require.NoError(t, err) - assert.Equal(t, "Bonjour", s.Translate("hello")) -} diff --git a/pkg/i18n/locales/de.json b/pkg/i18n/locales/de.json deleted file mode 100644 index 1b1b318..0000000 --- a/pkg/i18n/locales/de.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "app.boot.download-check": "Nach Updates suchen", - "app.boot.folder-check": "Setup-Check", - "app.boot.loaded-runtime": "Anwendung geladen", - "app.boot.server-check": "Überprüfung des Servers", - "app.boot.start-runtime": "Desktop starten", - "app.core.ui.search": "Suchen", - "app.lthn.chain.daemons.lethean-blockchain-export": "Blockchain-Export", - "app.lthn.chain.daemons.lethean-blockchain-import": "Blockchain-Import", - "app.lthn.chain.daemons.lethean-wallet-cli": "Brieftasche CLI", - "app.lthn.chain.daemons.lethean-wallet-rpc": "Wallet-RPC", - "app.lthn.chain.daemons.lethean-wallet-vpn-rpc": "Exit-Knoten-Wallet", - "app.lthn.chain.daemons.letheand": "Blockchain-Dienst", - "app.lthn.chain.desc.no_transactions": "In diesem Block waren keine Transaktionen enthalten", - "app.lthn.chain.description": "Lethean (LTHN) Blockchain-Statistiken", - "app.lthn.chain.heading": "Lethean Blockchain-Statistiken", - "app.lthn.chain.menu.blocks": "Blöcke", - "app.lthn.chain.menu.configuration": "Aufbau", - "app.lthn.chain.menu.raw_data": "Rohblockdaten", - "app.lthn.chain.menu.stats": "Statistiken", - "app.lthn.chain.table.age": "Alter", - "app.lthn.chain.table.depth": "Tiefe", - "app.lthn.chain.table.difficulty": "Schwierigkeit", - "app.lthn.chain.table.height": "Höhe", - "app.lthn.chain.table.reward": "BELOHNUNG", - "app.lthn.chain.table.time": "Zeit", - "app.lthn.chain.table.title.chain-status": "Blockchain-Status", - "app.lthn.chain.table.title.recent-blocks": "Kürzlich erstellte Blöcke", - "app.lthn.chain.title": "Blockchain Explorer", - "app.lthn.chain.words.alt_blocks_count": "Alt-Blöcke", - "app.lthn.chain.words.block_size": "Block Größe", - "app.lthn.chain.words.block_size_limit": "Begrenzung der Blockgröße", - "app.lthn.chain.words.chain_stat": "Kettenstatistik", - "app.lthn.chain.words.chain_stat_value": "Knoten gemeldeter Wert", - "app.lthn.chain.words.cumulative_difficulty": "Kumulative Schwierigkeit", - "app.lthn.chain.words.depth": "Tiefe vom oberen Block", - "app.lthn.chain.words.difficulty": "Schwierigkeit", - "app.lthn.chain.words.grey_peerlist_size": "P2P graue Kollegen", - "app.lthn.chain.words.hash": "Hash", - "app.lthn.chain.words.height": "Höhe", - "app.lthn.chain.words.incoming_connections_count": "P2P-Eingang", - "app.lthn.chain.words.install-blockchain": "Blockchain installieren", - "app.lthn.chain.words.last_block_time": "Synchronisiert mit Block:", - "app.lthn.chain.words.loading-data": "Laden von Blockchain-Daten", - "app.lthn.chain.words.major_version": "Hauptversion", - "app.lthn.chain.words.miner_transaction": "Miner-Transaktion", - "app.lthn.chain.words.miner_tx": "POW Miner-Transaktion", - "app.lthn.chain.words.minor_version": "Nebenversion", - "app.lthn.chain.words.nonce": "Lösung blockieren", - "app.lthn.chain.words.orphan_status": "Gültiger Block", - "app.lthn.chain.words.outgoing_connections_count": "P2P-Ausgang", - "app.lthn.chain.words.reward": "BELOHNUNG", - "app.lthn.chain.words.start_time": "Startzeit", - "app.lthn.chain.words.status": "Status", - "app.lthn.chain.words.target": "Ziel", - "app.lthn.chain.words.target_height": "Zielhöhe", - "app.lthn.chain.words.testnet": "Testnetz", - "app.lthn.chain.words.timestamp": "Zeitstempel", - "app.lthn.chain.words.top_height": "NEUESTER BLOCK", - "app.lthn.chain.words.tx_count": "Transaktionen insgesamt", - "app.lthn.chain.words.tx_pool_size": "ausstehende Transaktionen", - "app.lthn.chain.words.unlock_time": "Block entsperren", - "app.lthn.chain.words.valid": "Gültiger Block", - "app.lthn.chain.words.version": "Version der Blockstruktur", - "app.lthn.chain.words.white_peerlist_size": "P2P-Whitelist", - "app.lthn.console.title": "Konsole", - "app.lthn.wallet.button.create-wallet": "Brieftasche erstellen", - "app.lthn.wallet.button.restore-wallet": "Brieftasche wiederherstellen", - "app.lthn.wallet.button.unlock-wallet": "Freischalten", - "app.lthn.wallet.label.address": "Adresse", - "app.lthn.wallet.label.autosave": "Offene Brieftasche speichern", - "app.lthn.wallet.label.filename": "Dateiname", - "app.lthn.wallet.label.restore-height": "Höhe wiederherstellen", - "app.lthn.wallet.label.spend-key": "Schlüssel ausgeben", - "app.lthn.wallet.label.view-key": "Ansichtsschlüssel", - "app.lthn.wallet.label.wallet-password": "Brieftaschen-Passwort", - "app.lthn.wallet.label.wallet-password-confirm": "Passwort bestätigen", - "app.lthn.wallet.titles.new-wallet": "Neue Brieftasche erstellen", - "app.lthn.wallet.titles.restore-keys": "Von Schlüsseln wiederherstellen", - "app.lthn.wallet.titles.restore-seed": "Wiederherstellung aus Samen", - "app.lthn.wallet.titles.unlock-wallet": "Brieftasche entsperren", - "app.lthn.wallet.titles.wallet-transactions": "Wallet-Transaktionen", - "app.market.apps": "App-Marktplatz", - "app.market.dashboard": "Instrumententafel", - "app.market.installed": "Installierte Apps", - "app.market.no-apps-installed": "Sie haben keine Apps installiert.", - "app.market.view-installable-apps": "Installierbare Apps anzeigen", - "app.title": "Lethean Desktop", - "charts.network-hashrate.subtitle": "Daten bereitgestellt von", - "charts.network-hashrate.title": "Netzwerk-Hash-Rate", - "lang.de": "Deutsche", - "lang.en": "Englisch", - "lang.es": "Spanisch", - "lang.fr": "Französisch", - "lang.ru": "Russisch", - "lang.uk": "Ukrainisch (Ukraine)", - "lang.zh": "Chinesisch", - "menu.about": "Über", - "menu.activity": "Aktivität", - "menu.api": "api", - "menu.blockchain": "Blockchain", - "menu.build": "Bauen", - "menu.dashboard": "Instrumententafel", - "menu.docs": "Dokumentation", - "menu.documentation": "Dokumentation", - "menu.explorer": "Forscher", - "menu.help": "Hilfe", - "menu.hub-admin": "Administrator", - "menu.hub-client": "Klient", - "menu.hub-developer": "Entwickler", - "menu.hub-gateway": "TOR", - "menu.hub-server": "Server-Hub", - "menu.info": "info", - "menu.logout": "Abmelden", - "menu.mining": "Bergbau", - "menu.settings": "die Einstellungen", - "menu.vpn": "VPN", - "menu.wallet": "Brieftasche", - "menu.your-profile": "Dein Profil ", - "view.dashboard.description": "Lethean (LTHN) Web-App", - "view.dashboard.heading": "Lethean-Dashboard", - "view.dashboard.title": "Lethean (LTHN)", - "view.wallets.description": "Krypto-Wallet-Manager", - "view.wallets.heading": "Wallet-Manager", - "view.wallets.title": "Geldbörsen", - "words.actions.add": "Hinzufügen", - "words.actions.clone": "Klon", - "words.actions.edit": "Bearbeiten", - "words.actions.install": "Installieren", - "words.actions.new": "Neu", - "words.actions.remove": "Löschen", - "words.actions.report": "Bericht", - "words.actions.save": "sparen", - "words.states.installing": "Installieren", - "words.states.installing_desc": "Wir laden die ausführbaren Blockchain-Dateien von GitHub in Ihr Lethean-Benutzerverzeichnis herunter.", - "words.states.loading": "Wird geladen", - "words.states.not_installed": "Nicht installiert", - "words.states.not_installed_desc": "Klicken Sie auf Blockchain installieren, um die neueste Lethean Blockchain CLI . herunterzuladen", - "words.things.button": "Taste", - "words.things.documentation": "Dokumentation", - "words.things.menu": "Speisekarte", - "words.things.mining-pool": "Bergbaupool", - "words.things.page": "Seite", - "words.things.problem": "Problem", - "words.things.type": "Art", - "words.time.past.day": "vor einem Tag", - "words.time.past.days": "Vor Tagen", - "words.time.past.hour": "vor einer Stunde", - "words.time.past.hours": "Vor Stunden", - "words.time.past.minute": "vor einer Minute", - "words.time.past.minutes": "Vor ein paar Minuten", - "words.time.past.month": "vor einem Monat", - "words.time.past.months": " vor wenigen Monaten", - "words.time.past.seconds": "vor ein paar Sekunden", - "words.time.past.year": "vor einem Jahr", - "words.time.past.years": "vor Jahren" -} diff --git a/pkg/i18n/locales/en.json b/pkg/i18n/locales/en.json deleted file mode 100644 index e878aa1..0000000 --- a/pkg/i18n/locales/en.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "app.boot.download-check": "Checking for Updates", - "app.boot.folder-check": "Setup Check", - "app.boot.loaded-runtime": "Application Loaded", - "app.boot.server-check": "Checking Server", - "app.boot.start-runtime": "Starting Desktop", - "app.core.ui.search": "Search", - "app.lthn.chain.daemons.lethean-blockchain-export": "Blockchain Export", - "app.lthn.chain.daemons.lethean-blockchain-import": "Blockchain Import", - "app.lthn.chain.daemons.lethean-wallet-cli": "Wallet CLI", - "app.lthn.chain.daemons.lethean-wallet-rpc": "Wallet RPC", - "app.lthn.chain.daemons.lethean-wallet-vpn-rpc": "Exit Node Wallet", - "app.lthn.chain.daemons.letheand": "Blockchain Service", - "app.lthn.chain.desc.no_transactions": "There were no transactions included in this block", - "app.lthn.chain.description": "Lethean (LTHN) Blockchain Stats", - "app.lthn.chain.heading": "Lethean Blockchain Stats", - "app.lthn.chain.menu.blocks": "Blocks", - "app.lthn.chain.menu.configuration": "Configuration", - "app.lthn.chain.menu.raw_data": "Raw Block Data", - "app.lthn.chain.menu.stats": "Stats", - "app.lthn.chain.table.age": "Age", - "app.lthn.chain.table.depth": "Depth", - "app.lthn.chain.table.difficulty": "Difficulty", - "app.lthn.chain.table.height": "Height", - "app.lthn.chain.table.reward": "Reward", - "app.lthn.chain.table.time": "Time", - "app.lthn.chain.table.title.chain-status": "Blockchain Status", - "app.lthn.chain.table.title.recent-blocks": "Recently Created Blocks", - "app.lthn.chain.title": "Blockchain Explorer", - "app.lthn.chain.words.alt_blocks_count": "Alt Blocks", - "app.lthn.chain.words.block_size": "Block Size", - "app.lthn.chain.words.block_size_limit": "Block Size Limit", - "app.lthn.chain.words.chain_stat": "Chain Stats", - "app.lthn.chain.words.chain_stat_value": "Node Reported Value", - "app.lthn.chain.words.cumulative_difficulty": "Cumulative Difficulty", - "app.lthn.chain.words.depth": "Depth from Top Block", - "app.lthn.chain.words.difficulty": "Difficulty", - "app.lthn.chain.words.grey_peerlist_size": "P2P Grey Peers", - "app.lthn.chain.words.hash": "Hash", - "app.lthn.chain.words.height": "Height", - "app.lthn.chain.words.incoming_connections_count": "P2P Incoming", - "app.lthn.chain.words.install-blockchain": "Install Blockchain", - "app.lthn.chain.words.last_block_time": "Synchronised to Block:", - "app.lthn.chain.words.loading-data": "Loading Blockchain Data", - "app.lthn.chain.words.major_version": "Major Version", - "app.lthn.chain.words.miner_transaction": "Miner Transaction", - "app.lthn.chain.words.miner_tx": "POW Miner Transaction", - "app.lthn.chain.words.minor_version": "Minor Version", - "app.lthn.chain.words.nonce": "Block Solution", - "app.lthn.chain.words.orphan_status": "Valid Block", - "app.lthn.chain.words.outgoing_connections_count": "P2P Out", - "app.lthn.chain.words.reward": "Reward", - "app.lthn.chain.words.start_time": "Start Time", - "app.lthn.chain.words.status": "Status", - "app.lthn.chain.words.target": "Target", - "app.lthn.chain.words.target_height": "Target Height", - "app.lthn.chain.words.testnet": "Testnet", - "app.lthn.chain.words.timestamp": "Timestamp", - "app.lthn.chain.words.top_height": "Newest Block", - "app.lthn.chain.words.tx_count": "Total Transactions", - "app.lthn.chain.words.tx_pool_size": "Pending Transactions", - "app.lthn.chain.words.unlock_time": "Unlock Block", - "app.lthn.chain.words.valid": "Valid Block", - "app.lthn.chain.words.version": "Block Structure Version", - "app.lthn.chain.words.white_peerlist_size": "P2P Whitelist", - "app.lthn.console.title": "Console", - "app.lthn.wallet.button.create-wallet": "Create Wallet", - "app.lthn.wallet.button.restore-wallet": "Restore Wallet", - "app.lthn.wallet.button.unlock-wallet": "Unlock", - "app.lthn.wallet.label.address": "Address", - "app.lthn.wallet.label.autosave": "Save Open Wallet", - "app.lthn.wallet.label.filename": "Filename", - "app.lthn.wallet.label.restore-height": "Restore Height", - "app.lthn.wallet.label.spend-key": "Spend Key", - "app.lthn.wallet.label.view-key": "View Key", - "app.lthn.wallet.label.wallet-password": "Wallet Password", - "app.lthn.wallet.label.wallet-password-confirm": "Confirm Password", - "app.lthn.wallet.titles.new-wallet": "Make New Wallet", - "app.lthn.wallet.titles.restore-keys": "Restore From Keys", - "app.lthn.wallet.titles.restore-seed": "Restore From Seed", - "app.lthn.wallet.titles.unlock-wallet": "Unlock Wallet", - "app.lthn.wallet.titles.wallet-transactions": "Wallet Transactions", - "app.market.apps": "App Marketplace", - "app.market.dashboard": "Dashboard", - "app.market.installed": "Installed Apps", - "app.market.no-apps-installed": "You have no apps installed.", - "app.market.view-installable-apps": "View Installable Apps", - "app.title": "Lethean Desktop", - "charts.network-hashrate.subtitle": "Data Provided by", - "charts.network-hashrate.title": "Network Hash Rate", - "lang.de": "German", - "lang.en": "English", - "lang.es": "Spanish", - "lang.fr": "French", - "lang.ru": "Russian", - "lang.uk": "Ukrainian (Ukraine)", - "lang.zh": "Chinese", - "menu.about": "About", - "menu.activity": "Activity", - "menu.api": "api", - "menu.blockchain": "Blockchain", - "menu.build": "Build", - "menu.dashboard": "Dashboard", - "menu.docs": "Documentation", - "menu.documentation": "Documentation", - "menu.explorer": "Explorer", - "menu.help": "Help", - "menu.hub-admin": "Admin Hub", - "menu.hub-client": "Client Hub", - "menu.hub-developer": "Developer", - "menu.hub-gateway": "Gateway", - "menu.hub-server": "Server Hub", - "menu.info": "info", - "menu.logout": "Sign Out", - "menu.mining": "Mining", - "menu.settings": "Settings", - "menu.vpn": "VPN", - "menu.wallet": "Wallet", - "menu.your-profile": "Your Profile", - "view.dashboard.description": "Lethean (LTHN) Web app", - "view.dashboard.heading": "Lethean Dashboard", - "view.dashboard.title": "Lethean (LTHN)", - "view.wallets.description": "Crypto Wallet Manager", - "view.wallets.heading": "Wallet Manager", - "view.wallets.title": "Wallets", - "words.actions.add": "Add", - "words.actions.clone": "Clone", - "words.actions.edit": "Edit", - "words.actions.install": "Install", - "words.actions.new": "New", - "words.actions.remove": "Remove", - "words.actions.report": "Report", - "words.actions.save": "Save", - "words.states.installing": "Installing", - "words.states.installing_desc": "We are downloading the blockchain executables from GitHub to your Lethean user directory.", - "words.states.loading": "Loading", - "words.states.not_installed": "Not Installed", - "words.states.not_installed_desc": "Click Install Blockchain to download the latest Lethean Blockchain CLI", - "words.things.button": "Button", - "words.things.documentation": "Documentation", - "words.things.menu": "Menu", - "words.things.mining-pool": "Mining Pool", - "words.things.page": "Page", - "words.things.problem": "Problem", - "words.things.type": "Type", - "words.time.past.day": "a day ago", - "words.time.past.days": "days ago", - "words.time.past.hour": "an hour ago", - "words.time.past.hours": "hours ago", - "words.time.past.minute": "a minute ago", - "words.time.past.minutes": "minutes ago", - "words.time.past.month": "a month ago", - "words.time.past.months": " months ago", - "words.time.past.seconds": "a few seconds ago", - "words.time.past.year": "a year ago", - "words.time.past.years": "years ago" -} diff --git a/pkg/i18n/locales/es.json b/pkg/i18n/locales/es.json deleted file mode 100644 index 4141eb6..0000000 --- a/pkg/i18n/locales/es.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "app.boot.download-check": "Comprobando actualizaciones", - "app.boot.folder-check": "Comprobación de configuración", - "app.boot.loaded-runtime": "Aplicación cargada", - "app.boot.server-check": "Servidor de comprobación", - "app.boot.start-runtime": "Iniciar escritorio", - "app.core.ui.search": "Buscar", - "app.lthn.chain.daemons.lethean-blockchain-export": "Exportación de Blockchain", - "app.lthn.chain.daemons.lethean-blockchain-import": "Importación de Blockchain", - "app.lthn.chain.daemons.lethean-wallet-cli": "CLI de Wallet", - "app.lthn.chain.daemons.lethean-wallet-rpc": "Monedero RPC", - "app.lthn.chain.daemons.lethean-wallet-vpn-rpc": "Salir de la billetera del nodo", - "app.lthn.chain.daemons.letheand": "Servicio Blockchain", - "app.lthn.chain.desc.no_transactions": "No hubo transacciones incluidas en este bloque", - "app.lthn.chain.description": "Estadísticas de Blockchain de Lethean (LTHN)", - "app.lthn.chain.heading": "Estadísticas de Lethean Blockchain", - "app.lthn.chain.menu.blocks": "bloques", - "app.lthn.chain.menu.configuration": "Configuración", - "app.lthn.chain.menu.raw_data": "Datos de bloque sin procesar", - "app.lthn.chain.menu.stats": "Estadísticas", - "app.lthn.chain.table.age": "años", - "app.lthn.chain.table.depth": "Profundidad", - "app.lthn.chain.table.difficulty": "Dificultad", - "app.lthn.chain.table.height": "Altura", - "app.lthn.chain.table.reward": "recompensa", - "app.lthn.chain.table.time": "hora", - "app.lthn.chain.table.title.chain-status": "Estado de blockchain", - "app.lthn.chain.table.title.recent-blocks": "Bloques creados recientemente", - "app.lthn.chain.title": "Explorador de blockchain", - "app.lthn.chain.words.alt_blocks_count": "Bloques alternativos", - "app.lthn.chain.words.block_size": "Tamaño de bloque", - "app.lthn.chain.words.block_size_limit": "Límite de tamaño de bloque", - "app.lthn.chain.words.chain_stat": "Estadísticas de la cadena", - "app.lthn.chain.words.chain_stat_value": "Valor informado del nodo", - "app.lthn.chain.words.cumulative_difficulty": "Dificultad Acumulativa", - "app.lthn.chain.words.depth": "Profundidad desde el bloque superior", - "app.lthn.chain.words.difficulty": "Dificultad", - "app.lthn.chain.words.grey_peerlist_size": "Compañeros grises P2P", - "app.lthn.chain.words.hash": "Picadillo", - "app.lthn.chain.words.height": "Altura", - "app.lthn.chain.words.incoming_connections_count": "P2P entrante", - "app.lthn.chain.words.install-blockchain": "Instalar Blockchain", - "app.lthn.chain.words.last_block_time": "Sincronizado para bloquear:", - "app.lthn.chain.words.loading-data": "Cargando datos de Blockchain", - "app.lthn.chain.words.major_version": "versión principal", - "app.lthn.chain.words.miner_transaction": "Transacción minera", - "app.lthn.chain.words.miner_tx": "Transacción de minero POW", - "app.lthn.chain.words.minor_version": "versión menor", - "app.lthn.chain.words.nonce": "Solución de bloque", - "app.lthn.chain.words.orphan_status": "Bloque válido", - "app.lthn.chain.words.outgoing_connections_count": "P2P hacia fuera", - "app.lthn.chain.words.reward": "recompensa", - "app.lthn.chain.words.start_time": "Hora de inicio", - "app.lthn.chain.words.status": "Estado", - "app.lthn.chain.words.target": "Objetivo", - "app.lthn.chain.words.target_height": "Altura objetivo", - "app.lthn.chain.words.testnet": "Testnet", - "app.lthn.chain.words.timestamp": "marca de tiempo", - "app.lthn.chain.words.top_height": "Bloque más nuevo", - "app.lthn.chain.words.tx_count": "Transacciones totales", - "app.lthn.chain.words.tx_pool_size": "Transacciones pendientes", - "app.lthn.chain.words.unlock_time": "Desbloquear bloque", - "app.lthn.chain.words.valid": "Bloque válido", - "app.lthn.chain.words.version": "Versión de estructura de bloque", - "app.lthn.chain.words.white_peerlist_size": "Lista blanca P2P", - "app.lthn.console.title": "Consola", - "app.lthn.wallet.button.create-wallet": "Crear billetera", - "app.lthn.wallet.button.restore-wallet": "Restaurar billetera", - "app.lthn.wallet.button.unlock-wallet": "Desbloquear", - "app.lthn.wallet.label.address": "Dirección", - "app.lthn.wallet.label.autosave": "Guardar billetera abierta", - "app.lthn.wallet.label.filename": "Nombre del archivo", - "app.lthn.wallet.label.restore-height": "Restaurar altura", - "app.lthn.wallet.label.spend-key": "Gastar clave", - "app.lthn.wallet.label.view-key": "Ver clave", - "app.lthn.wallet.label.wallet-password": "Contraseña de billetera", - "app.lthn.wallet.label.wallet-password-confirm": "Confirmar contraseña", - "app.lthn.wallet.titles.new-wallet": "Crear nueva billetera", - "app.lthn.wallet.titles.restore-keys": "Restaurar desde claves", - "app.lthn.wallet.titles.restore-seed": "Restaurar de semilla", - "app.lthn.wallet.titles.unlock-wallet": "Desbloquear billetera", - "app.lthn.wallet.titles.wallet-transactions": "Transacciones de billetera", - "app.market.apps": "Mercado de aplicaciones", - "app.market.dashboard": "Tablero", - "app.market.installed": "Aplicaciones instaladas", - "app.market.no-apps-installed": "No tienes aplicaciones instaladas.", - "app.market.view-installable-apps": "Ver aplicaciones instalables", - "app.title": "Escritorio Lethean", - "charts.network-hashrate.subtitle": "Datos proporcionados por", - "charts.network-hashrate.title": "Tasa de hash de red", - "lang.de": "alemán", - "lang.en": "Inglés", - "lang.es": "español", - "lang.fr": "francés", - "lang.ru": "ruso", - "lang.uk": "Ucraniano (Ucrania)", - "lang.zh": "chino", - "menu.about": "Acerca De", - "menu.activity": "Actividad", - "menu.api": "api", - "menu.blockchain": "Blockchain", - "menu.build": "Construir", - "menu.dashboard": "Tablero", - "menu.docs": "Documentación", - "menu.documentation": "Documentación", - "menu.explorer": "explorador", - "menu.help": "Ayuda", - "menu.hub-admin": "Administración", - "menu.hub-client": "Cliente", - "menu.hub-developer": "Desarrollador", - "menu.hub-gateway": "Puerta", - "menu.hub-server": "Centro de servidores", - "menu.info": "información", - "menu.logout": "Desconectar", - "menu.mining": "Minería", - "menu.settings": "Ajustes", - "menu.vpn": "VPN", - "menu.wallet": "billetera", - "menu.your-profile": "Tu perfil", - "view.dashboard.description": "Aplicación web Lethean (LTHN)", - "view.dashboard.heading": "Panel de Lethean", - "view.dashboard.title": "Lethean (LTHN)", - "view.wallets.description": "Administrador de criptomonedas", - "view.wallets.heading": "Administrador de billetera", - "view.wallets.title": "carteras", - "words.actions.add": "Añadir", - "words.actions.clone": "Clon", - "words.actions.edit": "Editar", - "words.actions.install": "instalar", - "words.actions.new": "nuevo", - "words.actions.remove": "retirar", - "words.actions.report": "informe", - "words.actions.save": "Salvar", - "words.states.installing": "Instalando", - "words.states.installing_desc": "Estamos descargando los ejecutables de blockchain de GitHub a su directorio de usuario de Lethean.", - "words.states.loading": "Cargando", - "words.states.not_installed": "No instalado", - "words.states.not_installed_desc": "Haga clic en Instalar Blockchain para descargar la última CLI de Lethean Blockchain", - "words.things.button": "Botón", - "words.things.documentation": "Documentación", - "words.things.menu": "menú", - "words.things.mining-pool": "Pool de minería", - "words.things.page": "Página", - "words.things.problem": "Problema", - "words.things.type": "Tipo", - "words.time.past.day": "HACE UN DIA", - "words.time.past.days": "hace días", - "words.time.past.hour": "hace una hora", - "words.time.past.hours": "horas atras", - "words.time.past.minute": "hace un minuto", - "words.time.past.minutes": "hace minutos", - "words.time.past.month": "hace un mes", - "words.time.past.months": " Hace meses", - "words.time.past.seconds": "hace unos segundos", - "words.time.past.year": "hace un año", - "words.time.past.years": "Hace años que" -} diff --git a/pkg/i18n/locales/fr.json b/pkg/i18n/locales/fr.json deleted file mode 100644 index 31de3a6..0000000 --- a/pkg/i18n/locales/fr.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "app.boot.download-check": "Vérification des mises à jour", - "app.boot.folder-check": "Vérification de la configuration", - "app.boot.loaded-runtime": "Application chargée", - "app.boot.server-check": "Vérification du serveur", - "app.boot.start-runtime": "Démarrage du bureau", - "app.core.ui.search": "Recherche", - "app.lthn.chain.daemons.lethean-blockchain-export": "Exportation de la blockchain", - "app.lthn.chain.daemons.lethean-blockchain-import": "Importation de blockchain", - "app.lthn.chain.daemons.lethean-wallet-cli": "Portefeuille CLI", - "app.lthn.chain.daemons.lethean-wallet-rpc": "Portefeuille RPC", - "app.lthn.chain.daemons.lethean-wallet-vpn-rpc": "Quitter le portefeuille de nœuds", - "app.lthn.chain.daemons.letheand": "Service de blockchain", - "app.lthn.chain.desc.no_transactions": "Il n'y avait aucune transaction incluse dans ce bloc", - "app.lthn.chain.description": "Statistiques de la chaîne de blocs Lethean (LTHN)", - "app.lthn.chain.heading": "Statistiques Lethean Blockchain", - "app.lthn.chain.menu.blocks": "Des blocs", - "app.lthn.chain.menu.configuration": "Configuration", - "app.lthn.chain.menu.raw_data": "Données de bloc brutes", - "app.lthn.chain.menu.stats": "statistiques", - "app.lthn.chain.table.age": "âge", - "app.lthn.chain.table.depth": "Profondeur", - "app.lthn.chain.table.difficulty": "difficulté", - "app.lthn.chain.table.height": "la taille", - "app.lthn.chain.table.reward": "Récompensé", - "app.lthn.chain.table.time": "Temps", - "app.lthn.chain.table.title.chain-status": "Statut de la blockchain", - "app.lthn.chain.table.title.recent-blocks": "Blocs récemment créés", - "app.lthn.chain.title": "Explorateur de blockchain", - "app.lthn.chain.words.alt_blocks_count": "Blocs alternatifs", - "app.lthn.chain.words.block_size": "Taille de bloc", - "app.lthn.chain.words.block_size_limit": "Limite de taille de bloc", - "app.lthn.chain.words.chain_stat": "Statistiques de la chaîne", - "app.lthn.chain.words.chain_stat_value": "Valeur signalée par le nœud", - "app.lthn.chain.words.cumulative_difficulty": "Difficulté cumulée", - "app.lthn.chain.words.depth": "Profondeur à partir du bloc supérieur", - "app.lthn.chain.words.difficulty": "difficulté", - "app.lthn.chain.words.grey_peerlist_size": "Pairs gris P2P", - "app.lthn.chain.words.hash": "Hacher", - "app.lthn.chain.words.height": "la taille", - "app.lthn.chain.words.incoming_connections_count": "P2P entrant", - "app.lthn.chain.words.install-blockchain": "Installer la blockchain", - "app.lthn.chain.words.last_block_time": "Synchronisé pour bloquer :", - "app.lthn.chain.words.loading-data": "Chargement des données de la blockchain", - "app.lthn.chain.words.major_version": "Version majeure", - "app.lthn.chain.words.miner_transaction": "Transaction de mineur", - "app.lthn.chain.words.miner_tx": "Transaction de mineur POW", - "app.lthn.chain.words.minor_version": "Version mineure", - "app.lthn.chain.words.nonce": "Bloquer la solution", - "app.lthn.chain.words.orphan_status": "Bloc valide", - "app.lthn.chain.words.outgoing_connections_count": "Sortie P2P", - "app.lthn.chain.words.reward": "Récompensé", - "app.lthn.chain.words.start_time": "Heure de début", - "app.lthn.chain.words.status": "Statut", - "app.lthn.chain.words.target": "Cible", - "app.lthn.chain.words.target_height": "Hauteur cible", - "app.lthn.chain.words.testnet": "Réseau de test", - "app.lthn.chain.words.timestamp": "horodatage", - "app.lthn.chain.words.top_height": "Bloc le plus récent", - "app.lthn.chain.words.tx_count": "Transactions totales", - "app.lthn.chain.words.tx_pool_size": "Opérations en attente", - "app.lthn.chain.words.unlock_time": "Débloquer le bloc", - "app.lthn.chain.words.valid": "Bloc valide", - "app.lthn.chain.words.version": "Version de structure de bloc", - "app.lthn.chain.words.white_peerlist_size": "Liste blanche P2P", - "app.lthn.console.title": "Console", - "app.lthn.wallet.button.create-wallet": "Créer un portefeuille", - "app.lthn.wallet.button.restore-wallet": "Restaurer le portefeuille", - "app.lthn.wallet.button.unlock-wallet": "Ouvrir", - "app.lthn.wallet.label.address": "Adresse", - "app.lthn.wallet.label.autosave": "Enregistrer le portefeuille ouvert", - "app.lthn.wallet.label.filename": "Nom de fichier", - "app.lthn.wallet.label.restore-height": "Restaurer la hauteur", - "app.lthn.wallet.label.spend-key": "Dépenser la clé", - "app.lthn.wallet.label.view-key": "Afficher la clé", - "app.lthn.wallet.label.wallet-password": "Mot de passe portefeuille", - "app.lthn.wallet.label.wallet-password-confirm": "Confirmez le mot de passe", - "app.lthn.wallet.titles.new-wallet": "Créer un nouveau portefeuille", - "app.lthn.wallet.titles.restore-keys": "Restaurer à partir des clés", - "app.lthn.wallet.titles.restore-seed": "Restaurer à partir de la graine", - "app.lthn.wallet.titles.unlock-wallet": "Déverrouiller le portefeuille", - "app.lthn.wallet.titles.wallet-transactions": "Transactions de portefeuille", - "app.market.apps": "Marché d'applications", - "app.market.dashboard": "Tableau de bord", - "app.market.installed": "Applications installées", - "app.market.no-apps-installed": "Aucune application n'est installée.", - "app.market.view-installable-apps": "Afficher les applications installables", - "app.title": "Bureau Lethean", - "charts.network-hashrate.subtitle": "Données fournies par", - "charts.network-hashrate.title": "Taux de hachage du réseau", - "lang.de": "Allemand", - "lang.en": "Anglais", - "lang.es": "Espanol", - "lang.fr": "Français", - "lang.ru": "Russe", - "lang.uk": "Ukrainien (Ukraine)", - "lang.zh": "chinois", - "menu.about": "A Propos", - "menu.activity": "activité", - "menu.api": "api", - "menu.blockchain": "Blockchain", - "menu.build": "Build", - "menu.dashboard": "Tableau de bord", - "menu.docs": "Documentation", - "menu.documentation": "Documentation", - "menu.explorer": "Explorateur", - "menu.help": "Aide", - "menu.hub-admin": "Administrateur", - "menu.hub-client": "Client", - "menu.hub-developer": "Développeur", - "menu.hub-gateway": "PASSERELLE", - "menu.hub-server": "Centre de serveurs", - "menu.info": "info", - "menu.logout": "Se déconnecter", - "menu.mining": "Exploitation minière", - "menu.settings": "Réglages", - "menu.vpn": "VPN", - "menu.wallet": "Portefeuille", - "menu.your-profile": "Votre profil", - "view.dashboard.description": "Application Web Lethean (LTHN)", - "view.dashboard.heading": "Tableau de bord Léthéan", - "view.dashboard.title": "Lethean (LTHN)", - "view.wallets.description": "Gestionnaire de portefeuille crypto", - "view.wallets.heading": "Gestionnaire de portefeuille", - "view.wallets.title": "Portefeuilles", - "words.actions.add": "Ajouter", - "words.actions.clone": "Cloner", - "words.actions.edit": "Modifier", - "words.actions.install": "Installer", - "words.actions.new": "Nouveau", - "words.actions.remove": "Retirer", - "words.actions.report": "rapport", - "words.actions.save": "sauvegarder", - "words.states.installing": "L'installation", - "words.states.installing_desc": "Nous téléchargeons les exécutables blockchain de GitHub dans votre répertoire utilisateur Lethean.", - "words.states.loading": "Chargement", - "words.states.not_installed": "Pas installé", - "words.states.not_installed_desc": "Cliquez sur Installer Blockchain pour télécharger la dernière CLI Lethean Blockchain", - "words.things.button": "Bouton", - "words.things.documentation": "Documentation", - "words.things.menu": "menu", - "words.things.mining-pool": "Piscine minière", - "words.things.page": "Page", - "words.things.problem": "Problème", - "words.things.type": "Type", - "words.time.past.day": "il y a un jour", - "words.time.past.days": "il y a quelques jours", - "words.time.past.hour": "il y a une heure", - "words.time.past.hours": "il y a des heures", - "words.time.past.minute": "Il y'a une minute", - "words.time.past.minutes": "il y a quelques minutes", - "words.time.past.month": "il y a un mois", - "words.time.past.months": " il y a des mois", - "words.time.past.seconds": "il ya quelques secondes", - "words.time.past.year": "il y a un an", - "words.time.past.years": "il y a des années" -} diff --git a/pkg/i18n/locales/ru.json b/pkg/i18n/locales/ru.json deleted file mode 100644 index 1f9ab4f..0000000 --- a/pkg/i18n/locales/ru.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "app.boot.download-check": "Проверка обновлений", - "app.boot.folder-check": "Проверка установки", - "app.boot.loaded-runtime": "Приложение загружено", - "app.boot.server-check": "Проверка сервера", - "app.boot.start-runtime": "Запуск рабочего стола", - "app.core.ui.search": "Поиск", - "app.lthn.chain.daemons.lethean-blockchain-export": "Блокчейн Экспорт", - "app.lthn.chain.daemons.lethean-blockchain-import": "Блокчейн Импорт", - "app.lthn.chain.daemons.lethean-wallet-cli": "Кошелек CLI", - "app.lthn.chain.daemons.lethean-wallet-rpc": "Кошелек RPC", - "app.lthn.chain.daemons.lethean-wallet-vpn-rpc": "Выход из кошелька узла", - "app.lthn.chain.daemons.letheand": "Блокчейн Сервис", - "app.lthn.chain.desc.no_transactions": "В этом блоке не было включенных транзакций", - "app.lthn.chain.description": "Статистика блокчейна Lethean (LTHN)", - "app.lthn.chain.heading": "Статистика Lethean Blockchain", - "app.lthn.chain.menu.blocks": "блоки", - "app.lthn.chain.menu.configuration": "конфигурация", - "app.lthn.chain.menu.raw_data": "Необработанные данные блока", - "app.lthn.chain.menu.stats": "Статистика", - "app.lthn.chain.table.age": "возраст", - "app.lthn.chain.table.depth": "Глубина", - "app.lthn.chain.table.difficulty": "Сложность", - "app.lthn.chain.table.height": "Высота", - "app.lthn.chain.table.reward": "Награда", - "app.lthn.chain.table.time": "Время", - "app.lthn.chain.table.title.chain-status": "Статус блокчейна", - "app.lthn.chain.table.title.recent-blocks": "Недавно созданные блоки", - "app.lthn.chain.title": "Исследователь блокчейн", - "app.lthn.chain.words.alt_blocks_count": "Альтернативные блоки", - "app.lthn.chain.words.block_size": "Размер блока", - "app.lthn.chain.words.block_size_limit": "Ограничение размера блока", - "app.lthn.chain.words.chain_stat": "Цепная статистика", - "app.lthn.chain.words.chain_stat_value": "Сообщаемое значение узла", - "app.lthn.chain.words.cumulative_difficulty": "Суммарная сложность", - "app.lthn.chain.words.depth": "Глубина от верхнего блока", - "app.lthn.chain.words.difficulty": "Сложность", - "app.lthn.chain.words.grey_peerlist_size": "P2P Серые узлы", - "app.lthn.chain.words.hash": "Хэш", - "app.lthn.chain.words.height": "Высота", - "app.lthn.chain.words.incoming_connections_count": "P2P In", - "app.lthn.chain.words.install-blockchain": "Установить блокчейн", - "app.lthn.chain.words.last_block_time": "Синхронизировано с блоком:", - "app.lthn.chain.words.loading-data": "Загрузка данных блокчейна", - "app.lthn.chain.words.major_version": "основная версия", - "app.lthn.chain.words.miner_transaction": "Шахтерская транзакция", - "app.lthn.chain.words.miner_tx": "Транзакция POW Miner", - "app.lthn.chain.words.minor_version": "минорная версия", - "app.lthn.chain.words.nonce": "Блочное решение", - "app.lthn.chain.words.orphan_status": "Действительный блок", - "app.lthn.chain.words.outgoing_connections_count": "P2P Out", - "app.lthn.chain.words.reward": "Награда", - "app.lthn.chain.words.start_time": "Начальное время", - "app.lthn.chain.words.status": "Статус", - "app.lthn.chain.words.target": "цель", - "app.lthn.chain.words.target_height": "Высота", - "app.lthn.chain.words.testnet": "Тестовая сеть", - "app.lthn.chain.words.timestamp": "Метка времени", - "app.lthn.chain.words.top_height": "Крайний блок", - "app.lthn.chain.words.tx_count": "Всего транзакций", - "app.lthn.chain.words.tx_pool_size": "Незавершенные транзакции", - "app.lthn.chain.words.unlock_time": "Разблокировать Блок", - "app.lthn.chain.words.valid": "Действительный блок", - "app.lthn.chain.words.version": "Версия структуры блока", - "app.lthn.chain.words.white_peerlist_size": "P2P Белый список", - "app.lthn.console.title": "Приставка", - "app.lthn.wallet.button.create-wallet": "Создать кошелек", - "app.lthn.wallet.button.restore-wallet": "Восстановить кошелек", - "app.lthn.wallet.button.unlock-wallet": "отпереть", - "app.lthn.wallet.label.address": "Адрес", - "app.lthn.wallet.label.autosave": "Сохранить открытый кошелек", - "app.lthn.wallet.label.filename": "Имя файла", - "app.lthn.wallet.label.restore-height": "С какого блока восстанавливаем?", - "app.lthn.wallet.label.spend-key": "Spend key", - "app.lthn.wallet.label.view-key": "View Key", - "app.lthn.wallet.label.wallet-password": "Пароль кошелька", - "app.lthn.wallet.label.wallet-password-confirm": "Подтвердите Пароль", - "app.lthn.wallet.titles.new-wallet": "Сделать новый кошелек", - "app.lthn.wallet.titles.restore-keys": "Восстановить из ключей", - "app.lthn.wallet.titles.restore-seed": "Восстановить из seed", - "app.lthn.wallet.titles.unlock-wallet": "Разблокировать кошелек", - "app.lthn.wallet.titles.wallet-transactions": "Транзакции", - "app.market.apps": "Магазин приложений", - "app.market.dashboard": "Приборная доска", - "app.market.installed": "Установленные приложения", - "app.market.no-apps-installed": "У вас не установлены приложения.", - "app.market.view-installable-apps": "Просмотр устанавливаемых приложений", - "app.title": "Lethean Рабочий стол", - "charts.network-hashrate.subtitle": "Данные предоставлены", - "charts.network-hashrate.title": "Скорость хэширования в сети", - "lang.de": "Немецкий", - "lang.en": "Английский", - "lang.es": "Испанский", - "lang.fr": "Французский", - "lang.ru": "Русский", - "lang.uk": "Украинский (Украина)", - "lang.zh": "Китайский язык", - "menu.about": "Около", - "menu.activity": "Активность", - "menu.api": "api", - "menu.blockchain": "Blockchain", - "menu.build": "Сборка", - "menu.dashboard": "Дашборд", - "menu.docs": "Документация", - "menu.documentation": "Документация", - "menu.explorer": "Explorer", - "menu.help": "Помощь", - "menu.hub-admin": "Админ", - "menu.hub-client": "Клиент", - "menu.hub-developer": "Разработчик", - "menu.hub-gateway": "Шлюз", - "menu.hub-server": "Серверный концентратор", - "menu.info": "Информация", - "menu.logout": "Выход", - "menu.mining": "Горнодобывающая промышленность", - "menu.settings": "Настройки", - "menu.vpn": "VPN", - "menu.wallet": "Кошелек", - "menu.your-profile": "Ваш профиль", - "view.dashboard.description": "Веб-приложение Lethean (LTHN)", - "view.dashboard.heading": "Панель управления Lethean", - "view.dashboard.title": "Lethean (LTHN)", - "view.wallets.description": "Менеджер крипто-кошелька", - "view.wallets.heading": "Менеджер кошелька", - "view.wallets.title": "Кошелёк", - "words.actions.add": "Добавить", - "words.actions.clone": "Клонировать", - "words.actions.edit": "Редактировать", - "words.actions.install": "Установка", - "words.actions.new": "Новый", - "words.actions.remove": "Удалить", - "words.actions.report": "Отчет", - "words.actions.save": "Сохранить", - "words.states.installing": "Установка", - "words.states.installing_desc": "Мы загружаем исполняемые файлы блокчейна с GitHub в ваш каталог пользователей Lethean.", - "words.states.loading": "погрузка", - "words.states.not_installed": "Не установлено", - "words.states.not_installed_desc": "Нажмите «Установить блокчейн», чтобы загрузить последнюю версию интерфейса командной строки Lethean Blockchain.", - "words.things.button": "Кнопка", - "words.things.documentation": "Документация", - "words.things.menu": "Меню", - "words.things.mining-pool": "Майнинг пул", - "words.things.page": "Страница", - "words.things.problem": "Проблема", - "words.things.type": "Тип", - "words.time.past.day": "Предыдущий день", - "words.time.past.days": "дней назад", - "words.time.past.hour": "час назад", - "words.time.past.hours": "несколько часов назад", - "words.time.past.minute": "минуту назад", - "words.time.past.minutes": "несколько минут назад", - "words.time.past.month": "месяц назад", - "words.time.past.months": " несколько месяцев назад", - "words.time.past.seconds": "несколько секунд назад", - "words.time.past.year": "год назад", - "words.time.past.years": "много лет назад" -} diff --git a/pkg/i18n/locales/uk.json b/pkg/i18n/locales/uk.json deleted file mode 100644 index 8f413e6..0000000 --- a/pkg/i18n/locales/uk.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "app.boot.download-check": "Перевірка наявності оновлень", - "app.boot.folder-check": "Перевірка налаштування", - "app.boot.loaded-runtime": "Завантажено програму", - "app.boot.server-check": "Перевірка сервера", - "app.boot.start-runtime": "Запуск робочого столу", - "app.core.ui.search": "Пошук", - "app.lthn.chain.daemons.lethean-blockchain-export": "Експорт блокчейну", - "app.lthn.chain.daemons.lethean-blockchain-import": "Імпорт блокчейну", - "app.lthn.chain.daemons.lethean-wallet-cli": "CLI гаманця", - "app.lthn.chain.daemons.lethean-wallet-rpc": "RPC Wallet", - "app.lthn.chain.daemons.lethean-wallet-vpn-rpc": "Вийдіть з Node Wallet", - "app.lthn.chain.daemons.letheand": "Сервіс блокчейн", - "app.lthn.chain.desc.no_transactions": "Не було жодних транзакцій, включених до цього блоку", - "app.lthn.chain.description": "Статистика блокчейну Lethean (LTHN).", - "app.lthn.chain.heading": "Статистика блокчейну Lethean", - "app.lthn.chain.menu.blocks": "Блоки", - "app.lthn.chain.menu.configuration": "Конфігурація", - "app.lthn.chain.menu.raw_data": "Необроблені дані блоку", - "app.lthn.chain.menu.stats": "Статистика", - "app.lthn.chain.table.age": "Вік", - "app.lthn.chain.table.depth": "Глибина", - "app.lthn.chain.table.difficulty": "складність", - "app.lthn.chain.table.height": "Висота", - "app.lthn.chain.table.reward": "Нагорода", - "app.lthn.chain.table.time": "Час", - "app.lthn.chain.table.title.chain-status": "Стан блокчейну", - "app.lthn.chain.table.title.recent-blocks": "Нещодавно створені блоки", - "app.lthn.chain.title": "Blockchain Explorer", - "app.lthn.chain.words.alt_blocks_count": "Альтернативні блоки", - "app.lthn.chain.words.block_size": "Розмір блоку", - "app.lthn.chain.words.block_size_limit": "Обмеження розміру блоку", - "app.lthn.chain.words.chain_stat": "Статистика ланцюга", - "app.lthn.chain.words.chain_stat_value": "Повідомлене значення вузла", - "app.lthn.chain.words.cumulative_difficulty": "Сукупна складність", - "app.lthn.chain.words.depth": "Глибина від верхнього блоку", - "app.lthn.chain.words.difficulty": "складність", - "app.lthn.chain.words.grey_peerlist_size": "P2P Grey Peers", - "app.lthn.chain.words.hash": "Хеш", - "app.lthn.chain.words.height": "Висота", - "app.lthn.chain.words.incoming_connections_count": "P2P вхідні", - "app.lthn.chain.words.install-blockchain": "Встановіть блокчейн", - "app.lthn.chain.words.last_block_time": "Синхронізовано з блокуванням:", - "app.lthn.chain.words.loading-data": "Завантаження даних Blockchain", - "app.lthn.chain.words.major_version": "Основна версія", - "app.lthn.chain.words.miner_transaction": "Транзакція майнера", - "app.lthn.chain.words.miner_tx": "Транзакція майнера для військовополонених", - "app.lthn.chain.words.minor_version": "Друга версія", - "app.lthn.chain.words.nonce": "Блок рішення", - "app.lthn.chain.words.orphan_status": "Дійсний блок", - "app.lthn.chain.words.outgoing_connections_count": "Вихід P2P", - "app.lthn.chain.words.reward": "Нагорода", - "app.lthn.chain.words.start_time": "Час початку", - "app.lthn.chain.words.status": "статус", - "app.lthn.chain.words.target": "Ціль", - "app.lthn.chain.words.target_height": "Цільова висота", - "app.lthn.chain.words.testnet": "Testnet", - "app.lthn.chain.words.timestamp": "Відмітка часу", - "app.lthn.chain.words.top_height": "Найновіший блок", - "app.lthn.chain.words.tx_count": "Загальна кількість транзакцій", - "app.lthn.chain.words.tx_pool_size": "Транзакції в очікуванні", - "app.lthn.chain.words.unlock_time": "Розблокувати блок", - "app.lthn.chain.words.valid": "Дійсний блок", - "app.lthn.chain.words.version": "Версія блокової структури", - "app.lthn.chain.words.white_peerlist_size": "Білий список P2P", - "app.lthn.console.title": "консоль", - "app.lthn.wallet.button.create-wallet": "створити гаманець", - "app.lthn.wallet.button.restore-wallet": "Відновити гаманець", - "app.lthn.wallet.button.unlock-wallet": "розблокувати", - "app.lthn.wallet.label.address": "Адреса", - "app.lthn.wallet.label.autosave": "Зберегти Відкрийте гаманець", - "app.lthn.wallet.label.filename": "Ім'я файлу", - "app.lthn.wallet.label.restore-height": "Відновити висоту", - "app.lthn.wallet.label.spend-key": "Ключ витрат", - "app.lthn.wallet.label.view-key": "Ключ перегляду", - "app.lthn.wallet.label.wallet-password": "Пароль гаманця", - "app.lthn.wallet.label.wallet-password-confirm": "Підтвердьте пароль", - "app.lthn.wallet.titles.new-wallet": "Створіть новий гаманець", - "app.lthn.wallet.titles.restore-keys": "Відновити з ключів", - "app.lthn.wallet.titles.restore-seed": "Відновити з насіння", - "app.lthn.wallet.titles.unlock-wallet": "Розблокувати гаманець", - "app.lthn.wallet.titles.wallet-transactions": "Трансакції гаманця", - "app.market.apps": "App Marketplace", - "app.market.dashboard": "Панель приладів", - "app.market.installed": "Встановлені програми", - "app.market.no-apps-installed": "У вас не встановлено жодної програми.", - "app.market.view-installable-apps": "Переглянути додатки, які можна встановити", - "app.title": "Lethean Робочий стіл", - "charts.network-hashrate.subtitle": "Дані надані", - "charts.network-hashrate.title": "Швидкість хеш-мережі", - "lang.de": "Німецька", - "lang.en": "Англійська", - "lang.es": "Іспанська", - "lang.fr": "Французька", - "lang.ru": "російський", - "lang.uk": "українська (Україна)", - "lang.zh": "Китайська", - "menu.about": "Про", - "menu.activity": "Діяльність", - "menu.api": "Api", - "menu.blockchain": "Блокчейн", - "menu.build": "Будувати", - "menu.dashboard": "Панель приладів", - "menu.docs": "Документація", - "menu.documentation": "Документація", - "menu.explorer": "Explorer", - "menu.help": "Довідка", - "menu.hub-admin": "Адмін", - "menu.hub-client": "Клієнт", - "menu.hub-developer": "Розробник", - "menu.hub-gateway": "Шлюз", - "menu.hub-server": "Центр серверів", - "menu.info": "інформація", - "menu.logout": "Вийти з аккаунта", - "menu.mining": "Видобуток корисних копалин", - "menu.settings": "налаштування", - "menu.vpn": "VPN", - "menu.wallet": "Гаманець", - "menu.your-profile": "Ваш профіль", - "view.dashboard.description": "Веб-додаток Lethean (LTHN).", - "view.dashboard.heading": "Приладова панель Lethean", - "view.dashboard.title": "Lethean (LTHN)", - "view.wallets.description": "Менеджер криптовалютного гаманця", - "view.wallets.heading": "Менеджер гаманця", - "view.wallets.title": "Гаманці", - "words.actions.add": "Додати", - "words.actions.clone": "Клон", - "words.actions.edit": "редагувати", - "words.actions.install": "встановити", - "words.actions.new": "новий", - "words.actions.remove": "Видалити", - "words.actions.report": "звіт", - "words.actions.save": "зберегти", - "words.states.installing": "Встановлення", - "words.states.installing_desc": "Ми завантажуємо виконувані файли блокчейна з GitHub у ваш каталог користувачів Lethean.", - "words.states.loading": "Завантаження", - "words.states.not_installed": "Не встановлено", - "words.states.not_installed_desc": "Натисніть Встановити Blockchain, щоб завантажити останню версію Lethean Blockchain CLI", - "words.things.button": "Кнопка", - "words.things.documentation": "Документація", - "words.things.menu": "меню", - "words.things.mining-pool": "Майнінг-пул", - "words.things.page": "сторінка", - "words.things.problem": "Проблема", - "words.things.type": "Тип", - "words.time.past.day": "день тому", - "words.time.past.days": "днів тому", - "words.time.past.hour": "годину тому", - "words.time.past.hours": "годин тому", - "words.time.past.minute": "хвилину тому", - "words.time.past.minutes": "хвилин тому", - "words.time.past.month": "місяць тому", - "words.time.past.months": " місяців тому", - "words.time.past.seconds": "кілька секунд тому", - "words.time.past.year": "рік назад", - "words.time.past.years": "багато років тому" -} diff --git a/pkg/i18n/locales/zh.json b/pkg/i18n/locales/zh.json deleted file mode 100644 index f3167b3..0000000 --- a/pkg/i18n/locales/zh.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "app.boot.download-check": "查询更新", - "app.boot.folder-check": "设置检查", - "app.boot.loaded-runtime": "应用程序已加载", - "app.boot.server-check": "检查服务器", - "app.boot.start-runtime": "启动桌面", - "app.core.ui.search": "搜索", - "app.lthn.chain.daemons.lethean-blockchain-export": "区块链导出", - "app.lthn.chain.daemons.lethean-blockchain-import": "区块链导入", - "app.lthn.chain.daemons.lethean-wallet-cli": "钱包命令行界面(CLI)", - "app.lthn.chain.daemons.lethean-wallet-rpc": "钱包远程过程调用(RPC)", - "app.lthn.chain.daemons.lethean-wallet-vpn-rpc": "出口节点钱包", - "app.lthn.chain.daemons.letheand": "区块链服务", - "app.lthn.chain.desc.no_transactions": "此区块中不包含任何交易", - "app.lthn.chain.description": "Lethean (LTHN) 区块链统计", - "app.lthn.chain.heading": "Lethean 区块链统计数据", - "app.lthn.chain.menu.blocks": "块", - "app.lthn.chain.menu.configuration": "组态", - "app.lthn.chain.menu.raw_data": "原始块数据", - "app.lthn.chain.menu.stats": "统计资料", - "app.lthn.chain.table.age": "年龄", - "app.lthn.chain.table.depth": "深度", - "app.lthn.chain.table.difficulty": "困难", - "app.lthn.chain.table.height": "高度", - "app.lthn.chain.table.reward": "奖励", - "app.lthn.chain.table.time": "时间", - "app.lthn.chain.table.title.chain-status": "区块链状态", - "app.lthn.chain.table.title.recent-blocks": "最近创建的块", - "app.lthn.chain.title": "区块链浏览器", - "app.lthn.chain.words.alt_blocks_count": "替代块", - "app.lthn.chain.words.block_size": "块大小", - "app.lthn.chain.words.block_size_limit": "块大小限制", - "app.lthn.chain.words.chain_stat": "连锁统计", - "app.lthn.chain.words.chain_stat_value": "节点报告值", - "app.lthn.chain.words.cumulative_difficulty": "累积难度", - "app.lthn.chain.words.depth": "顶块深度", - "app.lthn.chain.words.difficulty": "困难", - "app.lthn.chain.words.grey_peerlist_size": "P2P 灰色同行", - "app.lthn.chain.words.hash": "哈希", - "app.lthn.chain.words.height": "高度", - "app.lthn.chain.words.incoming_connections_count": "P2P传入", - "app.lthn.chain.words.install-blockchain": "安装区块链", - "app.lthn.chain.words.last_block_time": "同步到块:", - "app.lthn.chain.words.loading-data": "加载区块链数据", - "app.lthn.chain.words.major_version": "主要版本", - "app.lthn.chain.words.miner_transaction": "", - "app.lthn.chain.words.miner_tx": "POW 矿工交易", - "app.lthn.chain.words.minor_version": "次要版本", - "app.lthn.chain.words.nonce": "块解决方案", - "app.lthn.chain.words.orphan_status": "有效区块", - "app.lthn.chain.words.outgoing_connections_count": "点对点输出", - "app.lthn.chain.words.reward": "奖励", - "app.lthn.chain.words.start_time": "开始时间", - "app.lthn.chain.words.status": "状态", - "app.lthn.chain.words.target": "目标", - "app.lthn.chain.words.target_height": "目标高度", - "app.lthn.chain.words.testnet": "测试网", - "app.lthn.chain.words.timestamp": "时间戳", - "app.lthn.chain.words.top_height": "最新区块", - "app.lthn.chain.words.tx_count": "交易总额", - "app.lthn.chain.words.tx_pool_size": "待交易", - "app.lthn.chain.words.unlock_time": "解锁方块", - "app.lthn.chain.words.valid": "有效区块", - "app.lthn.chain.words.version": "块结构版本", - "app.lthn.chain.words.white_peerlist_size": "P2P白名单", - "app.lthn.console.title": "安慰", - "app.lthn.wallet.button.create-wallet": "创建钱包", - "app.lthn.wallet.button.restore-wallet": "恢复钱包", - "app.lthn.wallet.button.unlock-wallet": "开锁", - "app.lthn.wallet.label.address": "地址", - "app.lthn.wallet.label.autosave": "保存开设钱包", - "app.lthn.wallet.label.filename": "文件名", - "app.lthn.wallet.label.restore-height": "恢复高度", - "app.lthn.wallet.label.spend-key": "花费密钥", - "app.lthn.wallet.label.view-key": "查看密钥", - "app.lthn.wallet.label.wallet-password": "钱包密码", - "app.lthn.wallet.label.wallet-password-confirm": "确认密码", - "app.lthn.wallet.titles.new-wallet": "创建新钱包", - "app.lthn.wallet.titles.restore-keys": "恢复钱包(密钥)", - "app.lthn.wallet.titles.restore-seed": "恢复钱包(种子)", - "app.lthn.wallet.titles.unlock-wallet": "解锁钱包", - "app.lthn.wallet.titles.wallet-transactions": "钱包交易", - "app.market.apps": "应用市场", - "app.market.dashboard": "仪表板", - "app.market.installed": "已安装的应用程序", - "app.market.no-apps-installed": "您没有安装任何应用程序。", - "app.market.view-installable-apps": "查看可安装的应用程序", - "app.title": "Lethean 桌面", - "charts.network-hashrate.subtitle": "数据提供者", - "charts.network-hashrate.title": "网络哈希率", - "lang.de": "德语", - "lang.en": "英语", - "lang.es": "西班牙语", - "lang.fr": "法国", - "lang.ru": "俄语", - "lang.uk": "乌克兰语(乌克兰)", - "lang.zh": "中文", - "menu.about": "关于", - "menu.activity": "活动", - "menu.api": "应用程序接口(API)", - "menu.blockchain": "区块链", - "menu.build": "建立", - "menu.dashboard": "仪表盘", - "menu.docs": "文档", - "menu.documentation": "文档", - "menu.explorer": "资源管理器", - "menu.help": "帮助", - "menu.hub-admin": "行政", - "menu.hub-client": "客户", - "menu.hub-developer": "开发人员", - "menu.hub-gateway": "网关", - "menu.hub-server": "服务器中心", - "menu.info": "信息", - "menu.logout": "登出", - "menu.mining": "矿业", - "menu.settings": "设置", - "menu.vpn": "虚拟专用网", - "menu.wallet": "钱包", - "menu.your-profile": "您的个人资料", - "view.dashboard.description": "Lethean (LTHN) 网络应用程序", - "view.dashboard.heading": "Lethean仪表盘", - "view.dashboard.title": "Lethean (LTHN)", - "view.wallets.description": "加密钱包管理器", - "view.wallets.heading": "钱包管理器", - "view.wallets.title": "皮夹", - "words.actions.add": "添加", - "words.actions.clone": "复制", - "words.actions.edit": "编辑", - "words.actions.install": "安装", - "words.actions.new": "新", - "words.actions.remove": "去掉", - "words.actions.report": "报告", - "words.actions.save": "保存", - "words.states.installing": "正在安装", - "words.states.installing_desc": "我们正在将区块链可执行文件从 GitHub 下载到您的 Lethean 用户目录。", - "words.states.loading": "装载", - "words.states.not_installed": "未安装", - "words.states.not_installed_desc": "单击安装区块链以下载最新的 Lethean 区块链命令行界面(CLI)", - "words.things.button": "按键", - "words.things.documentation": "文档", - "words.things.menu": "菜单", - "words.things.mining-pool": "矿池", - "words.things.page": "页面", - "words.things.problem": "问题", - "words.things.type": "类型", - "words.time.past.day": "一天前", - "words.time.past.days": "几天前", - "words.time.past.hour": "一小时前", - "words.time.past.hours": "小时前", - "words.time.past.minute": "一分钟前", - "words.time.past.minutes": "几分钟前", - "words.time.past.month": "一个月前", - "words.time.past.months": " 几个月前", - "words.time.past.seconds": "几秒钟前", - "words.time.past.year": "一年前", - "words.time.past.years": "几年前" -} diff --git a/pkg/i18n/testdata/en.json b/pkg/i18n/testdata/en.json deleted file mode 100644 index f750bd1..0000000 --- a/pkg/i18n/testdata/en.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "greeting": "Hello" -} diff --git a/pkg/i18n/testdata/es.json b/pkg/i18n/testdata/es.json deleted file mode 100644 index cb562c2..0000000 --- a/pkg/i18n/testdata/es.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "greeting": "Hola" -} diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go index 5f9e5ae..80f315e 100644 --- a/pkg/runtime/runtime.go +++ b/pkg/runtime/runtime.go @@ -4,11 +4,8 @@ import ( "context" "fmt" - "github.com/Snider/Core/pkg/config" "github.com/Snider/Core/pkg/core" "github.com/Snider/Core/pkg/crypt" - "github.com/Snider/Core/pkg/display" - "github.com/Snider/Core/pkg/i18n" "github.com/Snider/Core/pkg/workspace" "github.com/wailsapp/wails/v3/pkg/application" ) @@ -18,10 +15,7 @@ import ( type Runtime struct { app *application.App Core *core.Core - Config *config.Service - Display *display.Service Crypt *crypt.Service - I18n *i18n.Service Workspace *workspace.Service } @@ -35,7 +29,7 @@ func NewWithFactories(app *application.App, factories map[string]ServiceFactory) core.WithWails(app), } - for _, name := range []string{"config", "display", "crypt", "i18n", "workspace"} { + for _, name := range []string{"crypt", "workspace"} { factory, ok := factories[name] if !ok { return nil, fmt.Errorf("service %s factory not provided", name) @@ -55,22 +49,10 @@ func NewWithFactories(app *application.App, factories map[string]ServiceFactory) } // --- Type Assertions --- - configSvc, ok := services["config"].(*config.Service) - if !ok { - return nil, fmt.Errorf("config service has unexpected type") - } - displaySvc, ok := services["display"].(*display.Service) - if !ok { - return nil, fmt.Errorf("display service has unexpected type") - } cryptSvc, ok := services["crypt"].(*crypt.Service) if !ok { return nil, fmt.Errorf("crypt service has unexpected type") } - i18nSvc, ok := services["i18n"].(*i18n.Service) - if !ok { - return nil, fmt.Errorf("i18n service has unexpected type") - } workspaceSvc, ok := services["workspace"].(*workspace.Service) if !ok { return nil, fmt.Errorf("workspace service has unexpected type") @@ -79,10 +61,7 @@ func NewWithFactories(app *application.App, factories map[string]ServiceFactory) rt := &Runtime{ app: app, Core: coreInstance, - Config: configSvc, - Display: displaySvc, Crypt: cryptSvc, - I18n: i18nSvc, Workspace: workspaceSvc, } @@ -92,10 +71,7 @@ func NewWithFactories(app *application.App, factories map[string]ServiceFactory) // New creates and wires together all application services. func New(app *application.App) (*Runtime, error) { return NewWithFactories(app, map[string]ServiceFactory{ - "config": func() (any, error) { return config.New() }, - "display": func() (any, error) { return display.New() }, "crypt": func() (any, error) { return crypt.New() }, - "i18n": func() (any, error) { return i18n.New() }, "workspace": func() (any, error) { return workspace.New() }, }) } diff --git a/pkg/runtime/runtime_test.go b/pkg/runtime/runtime_test.go index 9f9b137..dd4329b 100644 --- a/pkg/runtime/runtime_test.go +++ b/pkg/runtime/runtime_test.go @@ -4,10 +4,7 @@ import ( "errors" "testing" - "github.com/Snider/Core/pkg/config" "github.com/Snider/Core/pkg/crypt" - "github.com/Snider/Core/pkg/display" - "github.com/Snider/Core/pkg/i18n" "github.com/Snider/Core/pkg/runtime" "github.com/Snider/Core/pkg/workspace" "github.com/stretchr/testify/assert" @@ -27,20 +24,14 @@ func TestNew(t *testing.T) { name: "Good path", app: nil, factories: map[string]runtime.ServiceFactory{ - "config": func() (any, error) { return &config.Service{}, nil }, - "display": func() (any, error) { return &display.Service{}, nil }, "crypt": func() (any, error) { return &crypt.Service{}, nil }, - "i18n": func() (any, error) { return &i18n.Service{}, nil }, "workspace": func() (any, error) { return &workspace.Service{}, nil }, }, expectErr: false, checkRuntime: func(t *testing.T, rt *runtime.Runtime) { assert.NotNil(t, rt) assert.NotNil(t, rt.Core) - assert.NotNil(t, rt.Config) - assert.NotNil(t, rt.Display) assert.NotNil(t, rt.Crypt) - assert.NotNil(t, rt.I18n) assert.NotNil(t, rt.Workspace) }, }, @@ -48,10 +39,7 @@ func TestNew(t *testing.T) { name: "Factory returns an error", app: nil, factories: map[string]runtime.ServiceFactory{ - "config": func() (any, error) { return &config.Service{}, nil }, - "display": func() (any, error) { return &display.Service{}, nil }, "crypt": func() (any, error) { return nil, errors.New("crypt service failed") }, - "i18n": func() (any, error) { return &i18n.Service{}, nil }, "workspace": func() (any, error) { return &workspace.Service{}, nil }, }, expectErr: true, @@ -61,23 +49,17 @@ func TestNew(t *testing.T) { name: "Factory returns wrong type", app: nil, factories: map[string]runtime.ServiceFactory{ - "config": func() (any, error) { return &config.Service{}, nil }, - "display": func() (any, error) { return "not a display service", nil }, - "crypt": func() (any, error) { return &crypt.Service{}, nil }, - "i18n": func() (any, error) { return &i18n.Service{}, nil }, + "crypt": func() (any, error) { return "not a crypt service", nil }, "workspace": func() (any, error) { return &workspace.Service{}, nil }, }, expectErr: true, - expectErrStr: "display service has unexpected type", + expectErrStr: "crypt service has unexpected type", }, { name: "With non-nil app", app: &application.App{}, factories: map[string]runtime.ServiceFactory{ - "config": func() (any, error) { return &config.Service{}, nil }, - "display": func() (any, error) { return &display.Service{}, nil }, "crypt": func() (any, error) { return &crypt.Service{}, nil }, - "i18n": func() (any, error) { return &i18n.Service{}, nil }, "workspace": func() (any, error) { return &workspace.Service{}, nil }, }, expectErr: false,