Compare commits

..

6 Commits

Author SHA1 Message Date
Lykin 66715d05a5 chore: add Korean support 2024-03-14 18:36:16 +08:00
Lykin 656e18afe5 chore: add `Privacy Policy` link (#181) 2024-03-14 18:36:16 +08:00
Lykin eca6bd523e perf: reduces page flicker during refresh 2024-03-14 17:12:46 +08:00
Lykin 13b9a38095 chore: add Russian support 2024-03-14 15:27:42 +08:00
Lykin de7cdb5bd4 perf: add behavior tracking instructions and switch options (#181) 2024-03-14 15:27:42 +08:00
Lykin e3ccb06a96 chore: update the year to 2024 2024-03-14 00:38:35 +08:00
25 changed files with 989 additions and 304 deletions

View File

@ -27,8 +27,8 @@ func (p *PreferencesStorage) DefaultPreferences() types.Preferences {
}
func (p *PreferencesStorage) getPreferences() (ret types.Preferences) {
b, err := p.storage.Load()
ret = p.DefaultPreferences()
b, err := p.storage.Load()
if err != nil {
return
}

View File

@ -24,6 +24,7 @@ func NewPreferences() Preferences {
ScanSize: consts.DEFAULT_SCAN_SIZE,
KeyIconStyle: 0,
CheckUpdate: true,
AllowTrack: true,
},
Editor: PreferencesEditor{
FontSize: consts.DEFAULT_FONT_SIZE,
@ -41,6 +42,7 @@ func NewPreferences() Preferences {
}
type PreferencesBehavior struct {
Welcomed bool `json:"welcomed" yaml:"welcomed"`
AsideWidth int `json:"asideWidth" yaml:"aside_width"`
WindowWidth int `json:"windowWidth" yaml:"window_width"`
WindowHeight int `json:"windowHeight" yaml:"window_height"`
@ -61,6 +63,7 @@ type PreferencesGeneral struct {
UseSysProxyHttp bool `json:"useSysProxyHttp" yaml:"use_sys_proxy_http,omitempty"`
CheckUpdate bool `json:"checkUpdate" yaml:"check_update"`
SkipVersion string `json:"skipVersion" yaml:"skip_version,omitempty"`
AllowTrack bool `json:"allowTrack" yaml:"allow_track"`
}
type PreferencesEditor struct {

View File

@ -8,8 +8,6 @@
</head>
<body spellcheck="false">
<div id="app"></div>
<script async data-website-id="ad6de51d-1e27-44a5-958d-319679c56aec"
src="https://analytics.tinycraft.cc/script.js"></script>
<script src="./src/main.js" type="module"></script>
</body>
</html>

View File

@ -8,11 +8,11 @@ import AddFieldsDialog from './components/dialogs/AddFieldsDialog.vue'
import AppContent from './AppContent.vue'
import GroupDialog from './components/dialogs/GroupDialog.vue'
import DeleteKeyDialog from './components/dialogs/DeleteKeyDialog.vue'
import { onMounted, ref, watch } from 'vue'
import { h, onMounted, ref, watch } from 'vue'
import usePreferencesStore from './stores/preferences.js'
import useConnectionStore from './stores/connections.js'
import { useI18n } from 'vue-i18n'
import { darkTheme } from 'naive-ui'
import { darkTheme, NButton, NSpace } from 'naive-ui'
import KeyFilterDialog from './components/dialogs/KeyFilterDialog.vue'
import { WindowSetDarkTheme, WindowSetLightTheme } from 'wailsjs/runtime/runtime.js'
import { darkThemeOverrides, themeOverrides } from '@/utils/theme.js'
@ -22,6 +22,8 @@ import ExportKeyDialog from '@/components/dialogs/ExportKeyDialog.vue'
import ImportKeyDialog from '@/components/dialogs/ImportKeyDialog.vue'
import { Info } from 'wailsjs/go/services/systemService.js'
import DecoderDialog from '@/components/dialogs/DecoderDialog.vue'
import { enableTrack, loadModule, trackEvent } from '@/utils/analytics.js'
import { endsWith } from 'lodash'
const prefStore = usePreferencesStore()
const connectionStore = useConnectionStore()
@ -36,10 +38,64 @@ onMounted(async () => {
if (prefStore.autoCheckUpdate) {
prefStore.checkForUpdate()
}
Info().then(({ data }) => {
// const {os, arch, version} = data
umami && umami.track('startup', data)
loadModule(prefStore.general.allowTrack !== false).then(() => {
Info().then(({ data }) => {
if (endsWith(data.version, 'dev')) {
enableTrack(false)
} else {
trackEvent('startup', data, true)
}
})
})
// show greetings and user behavior tracking statements
if (!!!prefStore.behavior.welcomed) {
const n = $notification.show({
title: () => i18n.t('dialogue.welcome.title'),
content: () => i18n.t('dialogue.welcome.content'),
// duration: 5000,
keepAliveOnHover: true,
closable: false,
meta: ' ',
action: () =>
h(
NSpace,
{},
{
default: () => [
h(
NButton,
{
secondary: true,
type: 'tertiary',
onClick: () => {
prefStore.setAsWelcomed(false)
n.destroy()
},
},
{
default: () => i18n.t('dialogue.welcome.reject'),
},
),
h(
NButton,
{
secondary: true,
type: 'primary',
onClick: () => {
prefStore.setAsWelcomed(true)
n.destroy()
},
},
{
default: () => i18n.t('dialogue.welcome.accept'),
},
),
],
},
),
})
}
} finally {
initializing.value = false
}

View File

@ -47,10 +47,7 @@ const keyType = redisTypes.JSON
const editingContent = ref('')
const displayValue = computed(() => {
if (props.loading) {
return ''
}
return decodeRedisKey(props.value)
return decodeRedisKey(props.value) || ''
})
const enableSave = computed(() => {
@ -144,9 +141,7 @@ defineExpose({
</n-button-group>
</div>
<div class="value-wrapper value-item-part flex-item-expand flex-box-v">
<n-spin :show="props.loading" />
<content-editor
v-show="!props.loading"
:content="displayValue"
:loading="props.loading"
:offset-key="props.keyPath"
@ -157,6 +152,7 @@ defineExpose({
@input="onInput"
@reset="onInput"
@save="onSave" />
<n-spin v-show="props.loading" />
</div>
<div class="value-footer flex-box-h">
<n-text v-if="showMemoryUsage">{{ $t('interface.memory_usage') }}: {{ formatBytes(props.size) }}</n-text>

View File

@ -77,10 +77,7 @@ const enableSave = computed(() => {
})
const displayValue = computed(() => {
if (props.loading) {
return ''
}
return viewAs.value || decodeRedisKey(props.value)
return viewAs.value || decodeRedisKey(props.value) || ''
})
const showMemoryUsage = computed(() => {
@ -205,9 +202,7 @@ defineExpose({
</n-button-group>
</div>
<div class="value-wrapper value-item-part flex-item-expand flex-box-v">
<n-spin :show="props.loading || converting" />
<content-editor
v-show="!(props.loading || converting)"
:content="displayValue"
:language="viewLanguage"
:loading="props.loading"
@ -218,6 +213,7 @@ defineExpose({
@input="onInput"
@reset="onInput"
@save="onSave" />
<n-spin v-show="props.loading || converting" />
</div>
<div class="value-footer flex-box-h">
<n-text v-if="!isNaN(props.length)">{{ $t('interface.length') }}: {{ props.length }}</n-text>

View File

@ -120,6 +120,7 @@ const onReload = async (selDecode, selFormat) => {
decode: targetDecode,
format: targetFormat,
matchPattern,
showLoading: false,
})
} finally {
}

View File

@ -37,7 +37,7 @@ const onOpenWebsite = () => {
<n-text class="about-link" @click="onOpenWebsite">{{ $t('dialogue.about.website') }}</n-text>
</n-space>
<div :style="{ color: themeVars.textColor3 }" class="about-copyright">
Copyright © 2023 Tinycraft.cc All rights reserved
Copyright © 2024 Tinycraft.cc All rights reserved
</div>
</n-space>
</n-modal>

View File

@ -146,6 +146,19 @@ const decoderColumns = computed(() => {
]
})
const onOpenPrivacy = () => {
let helpUrl = ''
switch (prefStore.currentLanguage) {
case 'zh':
helpUrl = 'https://redis.tinycraft.cc/zh/guide/privacy.html'
break
default:
helpUrl = 'https://redis.tinycraft.cc/guide/privacy.html'
break
}
BrowserOpenURL(helpUrl)
}
const openDecodeHelp = () => {
let helpUrl = ''
switch (prefStore.currentLanguage) {
@ -258,6 +271,14 @@ const onClose = () => {
{{ $t('preferences.general.auto_check_update') }}
</n-checkbox>
</n-form-item-gi>
<n-form-item-gi :label="$t('preferences.general.privacy')" :span="24">
<n-checkbox v-model:checked="prefStore.general.allowTrack">
{{ $t('preferences.general.allow_track') }}
<n-button style="text-decoration: underline" text type="primary" @click="onOpenPrivacy">
{{ $t('preferences.general.privacy') }}
</n-button>
</n-checkbox>
</n-form-item-gi>
</n-grid>
</n-form>
</n-tab-pane>

View File

@ -17,6 +17,7 @@ import { useRender } from '@/utils/render.js'
import wechatUrl from '@/assets/images/wechat_official.png'
import QRCode from '@/components/icons/QRCode.vue'
import Twitter from '@/components/icons/Twitter.vue'
import { trackEvent } from '@/utils/analytics.js'
const themeVars = useThemeVars()
const render = useRender()
@ -122,17 +123,17 @@ const onSelectPreferenceMenu = (key) => {
}
const openWechatOfficial = () => {
umami && umami.track('open', { target: 'wechat_official' })
trackEvent('open', { target: 'wechat_official' })
showWechat.value = true
}
const openX = () => {
umami && umami.track('open', { target: 'x' })
trackEvent('open', { target: 'x' })
BrowserOpenURL('https://twitter.com/LykinHuang')
}
const openGithub = () => {
umami && umami.track('open', { target: 'github' })
trackEvent('open', { target: 'github' })
BrowserOpenURL('https://github.com/tiny-craft/tiny-rdm')
}

View File

@ -46,7 +46,9 @@
"key_icon_style2": "Dot",
"key_icon_style3": "Common",
"update": "Update",
"auto_check_update": "Auto check for updates"
"auto_check_update": "Auto check for updates",
"privacy": "Privacy",
"allow_track": "Allows anonymous data to be collected"
},
"editor": {
"name": "Editor",
@ -382,6 +384,12 @@
"later": "Later",
"skip": "Skip This Version"
},
"welcome": {
"title": "Welcome to Tiny RDM",
"content": "In order to provide a better user experience, Tiny RDM collects some anonymous data to help optimize the software and improve the user experience, please rest assured that this does not involve your personal privacy information.\n\nIf you have any concerns, you can turn off this data collection feature at any time by going to Preferences. If you have any questions, feel free to contact the developer. I hope Tiny RDM can become your helpful assistant!",
"accept": "Help Improve",
"reject": "Reject"
},
"about": {
"source": "Source Code",
"website": "Official Website"

View File

@ -46,7 +46,9 @@
"key_icon_style2": "Punto",
"key_icon_style3": "Común",
"update": "Actualizar",
"auto_check_update": "Buscar actualizaciones automáticamente"
"auto_check_update": "Buscar actualizaciones automáticamente",
"privacy": "Política de Privacidad",
"allow_track": "Permitir recopilar datos anónimos"
},
"editor": {
"name": "Editor",
@ -382,6 +384,12 @@
"later": "Más tarde",
"skip": "Omitir esta versión"
},
"welcome": {
"title": "¡Bienvenido a Tiny RDM!",
"content": "Con el fin de brindar una mejor experiencia de usuario, Tiny RDM recopila algunos datos anónimos para ayudar a optimizar el software y mejorar la experiencia del usuario. Tenga la seguridad de que esto no involucrará su información de privacidad personal.\n\nSi tiene alguna inquietud, puede desactivar esta función de recopilación de datos en cualquier momento yendo a Preferencias. Si tiene alguna pregunta, no dude en ponerse en contacto con el desarrollador. ¡Espero que Tiny RDM pueda ser un buen asistente para usted!",
"accept": "Ayudar a Mejorar",
"reject": "Rechazar"
},
"about": {
"source": "Código fuente",
"website": "Sitio web oficial"

View File

@ -46,7 +46,9 @@
"key_icon_style2": "Point",
"key_icon_style3": "Commun",
"update": "Mise à jour",
"auto_check_update": "Vérifier automatiquement les mises à jour"
"auto_check_update": "Vérifier automatiquement les mises à jour",
"privacy": "Politique de confidentialité",
"allow_track": "Autoriser la collecte de données anonymes"
},
"editor": {
"name": "Éditeur",
@ -382,6 +384,12 @@
"later": "Plus tard",
"skip": "Ignorer cette version"
},
"welcome": {
"title": "Bienvenue dans Tiny RDM!",
"content": "Afin d'offrir une meilleure expérience utilisateur, Tiny RDM collecte certaines données anonymes pour aider à optimiser le logiciel et améliorer l'expérience utilisateur. Soyez assuré que cela n'implique pas vos informations personnelles et privées.\n\nSi vous avez des inquiétudes, vous pouvez désactiver cette fonction de collecte de données à tout moment en allant dans les Préférences. Si vous avez des questions, n'hésitez pas à contacter le développeur. J'espère que Tiny RDM pourra être un bon assistant pour vous!",
"accept": "Aider à Améliorer",
"reject": "Rejeter"
},
"about": {
"source": "Code source",
"website": "Site officiel"

View File

@ -6,6 +6,7 @@ import ko from './ko-kr'
import ja from './ja-jp'
import es from './es-es'
import fr from './fr-fr'
import ru from './ru-ru'
export const lang = {
en,
@ -14,6 +15,7 @@ export const lang = {
ja,
ko,
pt,
ru,
zh,
tw,
}

View File

@ -46,7 +46,9 @@
"key_icon_style2": "ドットタイプ",
"key_icon_style3": "共通アイコン",
"update": "更新",
"auto_check_update": "自動でアップデートを確認"
"auto_check_update": "自動でアップデートを確認",
"privacy": "プライバシーポリシー",
"allow_track": "匿名データの収集を許可する"
},
"editor": {
"name": "エディター",
@ -382,6 +384,12 @@
"later": "後で",
"skip": "このバージョンをスキップ"
},
"welcome": {
"title": "Tiny RDMをご利用いただきありがとうございます!",
"content": "ユーザーエクスペリエンスを改善するために、Tiny RDMは一部の匿名データを収集し、ソフトウェアの最適化とユーザーエクスペリエンスの向上に役立てています。個人プライバシー情報は含まれませんのでご安心ください。\n\nご不安な点がありましたら、いつでも「設定」から当該機能をオフにすることができます。ご不明な点がございましたら、開発者までお問い合わせください。Tiny RDMがお役に立てることを願っております。",
"accept": "改善の支援",
"reject": "拒否する"
},
"about": {
"source": "ソースコード",
"website": "公式ウェブサイト"

View File

@ -27,29 +27,31 @@
"preferences": {
"name": "설정",
"restore_defaults": "기본값 복원",
"font_tip": "다중 선택 지원, 목록에 없는 글꼴은 직접 입력",
"font_tip": "다중 선택 지원, 목록에 없는 폰트는 직접 입력하세요",
"general": {
"name": "일반",
"theme": "테마",
"theme_light": "밝은",
"theme_dark": "어두운",
"theme_light": "밝은 테마",
"theme_dark": "어두운 테마",
"theme_auto": "자동",
"language": "언어",
"system_lang": "시스템 언어 사용",
"font": "글꼴",
"font_tip": "글꼴 선택 또는 입력",
"font_size": "글꼴 크기",
"font": "폰트",
"font_tip": "폰트 선택 또는 이름 입력",
"font_size": "폰트 크기",
"scan_size": "SCAN 기본 크기",
"key_icon_style": "키 아이콘 스타일",
"key_icon_style0": "컴팩트",
"key_icon_style0": "간략한 타입",
"key_icon_style1": "전체 이름",
"key_icon_style2": "점",
"key_icon_style3": "일반",
"key_icon_style2": "점 타입",
"key_icon_style3": "일반 아이콘",
"update": "업데이트",
"auto_check_update": "자동 업데이트 확인"
"auto_check_update": "자동 업데이트 확인",
"privacy": "개인 정보 보호 정책",
"allow_track": "익명 데이터 수집 허용"
},
"editor": {
"name": "편집기",
"name": "에디터",
"show_linenum": "줄번호 표시",
"show_folding": "코드 폴딩 활성화",
"drop_text": "텍스트 드래그 앤 드롭 허용",
@ -68,14 +70,14 @@
"decoder_name": "이름",
"cmd_preview": "미리보기",
"status": "상태",
"auto_enabled": "자동 디코딩 활성화",
"auto_enabled": "자동 디코딩 활성화",
"help": "도움말"
}
},
"interface": {
"new_conn": "새 연결 추가",
"new_group": "새 그룹 추가",
"disconnect_all": "모두 연결 해제",
"disconnect_all": "모든 연결 끊기",
"status": "상태",
"filter": "필터",
"sort_conn": "연결 정렬",
@ -83,7 +85,7 @@
"open_db": "데이터베이스 열기",
"close_db": "데이터베이스 닫기",
"filter_key": "키 필터링",
"disconnect": "연결 해제",
"disconnect": "연결 끊기",
"dup_conn": "연결 복제",
"remove_conn": "연결 제거",
"edit_conn": "연결 편집",
@ -93,7 +95,7 @@
"import_conn": "연결 가져오기...",
"export_conn": "연결 내보내기...",
"ttl": "TTL",
"forever": "영구",
"forever": "영구",
"rename_key": "키 이름 변경",
"delete_key": "키 삭제",
"batch_delete_key": "키 일괄 삭제",
@ -101,33 +103,33 @@
"flush_db": "데이터베이스 플러시",
"check_mode": "선택 모드",
"quit_check_mode": "선택 모드 종료",
"delete_checked": "선택항목 삭제",
"export_checked": "선택항목 내보내기",
"ttl_checked": "선택항목 TTL 업데이트",
"delete_checked": "선택 항목 삭제",
"export_checked": "선택 항목 내보내기",
"ttl_checked": "선택 항목 TTL 업데이트",
"copy_value": "값 복사",
"edit_value": "값 편집",
"save_update": "변경사항 저장",
"score_filter_tip": "연산자 지원:\n= 같음\n!= 다름\n> 보다 큼\n>= 크거나 같음\n< 보다 작음\n<= 작거나 같음\ne.g. >3 점수가 3보다 큰 항목",
"score_filter_tip": "다음 연산자로 범위 일치 가능\n=: 같음\n!=: 다름\n>: 큼\n<: 작음\n>=: 크거나 같음\n<=: 작거나 같음\n예) 점수가 3 이상인 결과: >3",
"add_row": "행 삽입",
"edit_row": "행 편집",
"delete_row": "행 삭제",
"fullscreen": "전체화면",
"offscreen": "전체화면 종료",
"pin_edit": "고정 편집",
"pin_edit": "편집기 고정(저장 후 열린 상태 유지)",
"unpin_edit": "고정 해제",
"search": "검색",
"full_search": "전체 텍스트 검색",
"full_search_result": "'{pattern}' 일치하는 내용",
"full_search_result": "'{pattern}' 일치하는 내용",
"filter_field": "필드 필터링",
"filter_value": "값 필터링",
"length": "길이",
"entries": "항목",
"entries": "항목",
"memory_usage": "메모리 사용량",
"view_as": "보기 형식",
"view_as": "보기",
"decode_with": "디코딩/압축 해제",
"custom_decoder": "새 사용자 정의 디코더",
"reload": "새로고침",
"reload_disable": "전체 로드 후 새로고침",
"reload_disable": "전체 로드 후 새로고침 가능",
"auto_refresh": "자동 새로고침",
"refresh_interval": "새로고침 간격",
"open_connection": "연결 열기",
@ -135,24 +137,24 @@
"copy_key": "키 복사",
"save_value_succ": "값 저장됨!",
"copy_succ": "클립보드에 복사됨!",
"binary_key": "바이너리 키",
"binary_key": "바이너리 키 이름",
"remove_key": "키 제거",
"new_key": "새 키",
"load_more": "더 많은 키 로드",
"load_all": "남은 모든 키 로드",
"load_more_entries": "더 많은 항목 로드",
"load_all_entries": "모든 항목 로드",
"more_action": "더 많은 액션",
"load_more": "더 많은 키 불러오기",
"load_all": "남은 모든 키 불러오기",
"load_more_entries": "더 불러오기",
"load_all_entries": "모두 불러오기",
"more_action": "더 많은 작업",
"nonexist_tab_content": "선택한 키가 없거나 존재하지 않습니다. 새로고침 후 다시 시도하세요.",
"empty_server_content": "왼쪽 패널에서 연결을 선택하고 여세요",
"empty_server_list": "Redis 서버가 추가되지 않았습니다",
"action": "액션",
"empty_server_content": "왼쪽 패널에서 연결을 선택하고 열기",
"empty_server_list": "추가된 Redis 서버 없음",
"action": "작업",
"type": "유형",
"cli_welcome": "Tiny RDM Redis 콘솔에 오신 것을 환영합니다",
"retrieving_version": "새 버전 확인 중",
"cli_welcome": "Tiny RDM Redis 콘솔 환영합니다",
"retrieving_version": "업데이트 확인 중",
"sub_tab": {
"status": "상태",
"key_detail": "키 세부사항",
"key_detail": "키 상세정보",
"cli": "콘솔",
"slow_log": "슬로우 로그",
"cmd_monitor": "명령 모니터링",
@ -163,24 +165,24 @@
"server": "서버",
"browser": "데이터 브라우저",
"log": "로그",
"wechat_official": "위챗 공식 계정",
"follow_x": "\uD835\uDD4F 팔로우",
"wechat_official": "공식 계정",
"follow_x": "팔로우 \uD835\uDD4F",
"github": "Github"
},
"dialogue": {
"close_confirm": "이 연결({name})을 종료하시겠습니까?",
"edit_close_confirm": "편집하기 전에 관련 연결을 닫아야 합니다. 계속하시겠습니까?",
"opening_connection": "연결 열기 중...",
"edit_close_confirm": "편집 전에 관련 연결을 종료해야 합니다. 계속하시겠습니까?",
"opening_connection": "연결 중...",
"interrupt_connection": "취소",
"remove_tip": "{type} \"{name}\"(이)가 삭제됩니다",
"remove_group_tip": "\"{name}\" 그룹과 그 모든 연결이 삭제됩니다",
"remove_tip": "{type} \"{name}\"가 삭제됩니다",
"remove_group_tip": "그룹 \"{name}\"과 그 안의 모든 연결이 삭제됩니다",
"rename_binary_key_fail": "바이너리 키 이름 변경은 지원되지 않습니다",
"handle_succ": "성공!",
"handle_cancel": "작업이 취소되었습니다.",
"reload_succ": "새로고침!",
"reload_succ": "새로고침 완료!",
"field_required": "이 필드는 필수입니다",
"spec_field_required": "\"{key}\"(이)가 필요합니다",
"illegal_characters": "불법 문자 포함됨",
"spec_field_required": "\"{key}\"는 필수입니다",
"illegal_characters": "잘못된 문자가 포함되어 있습니다",
"connection": {
"new_title": "새 연결",
"edit_title": "연결 편집",
@ -189,278 +191,284 @@
"group": "그룹",
"conn_name": "이름",
"addr": "주소",
"usr": "사용자",
"usr": "사용자 이름",
"pwd": "비밀번호",
"name_tip": "연결 이름",
"addr_tip": "Redis 서버 주소",
"sock_tip": "Redis 유닉스 소켓 파일",
"usr_tip": "(선택) 인증 사용자",
"usr_tip": "(선택) 인증 사용자 이름",
"pwd_tip": "(선택) 인증 비밀번호 (Redis > 6.0)",
"test": "연결 테스트",
"test_succ": "Redis 서버에 성공적으로 연결되었습니다",
"test_fail": "연결 실패",
"parse_url_clipboard": "클립보드에서 URL 파싱",
"parse_pass": "Redis URL 파싱됨: {url}",
"parse_fail": "Redis URL 파싱 실패: {reason}",
"parse_url_clipboard": "클립보드에서 URL 분석",
"parse_pass": "Redis URL이 분석되었습니다: {url}",
"parse_fail": "Redis URL 분석 실패: {reason}",
"advn": {
"title": "고급",
"filter": "기본 키 필터",
"filter_tip": "로드할 키 패턴",
"separator": "키 구분",
"separator_tip": "키 경로 세그먼트 구분자",
"conn_timeout": "연결 제한시간",
"exec_timeout": "실행 제한시간",
"separator": "키 구분 기호",
"separator_tip": "키 경로 구분 기호",
"conn_timeout": "연결 시간 초과",
"exec_timeout": "실행 시간 초과",
"dbfilter_type": "데이터베이스 필터",
"dbfilter_all": "모두 표시",
"dbfilter_show": "선택 표시",
"dbfilter_hide": "선택 숨김",
"dbfilter_show": "선택 항목 표시",
"dbfilter_hide": "선택 항목 숨기기",
"dbfilter_show_title": "표시할 데이터베이스",
"dbfilter_hide_title": "숨길 데이터베이스",
"dbfilter_input": "데이터베이스 인덱스 입력",
"dbfilter_input_tip": "Enter 키 입력하여 확인",
"dbfilter_input_tip": "Enter를 눌러 확인",
"key_view": "기본 키 보기",
"key_view_tree": "트리 보기",
"key_view_list": "목록 보기",
"load_size": "키 로드 갯수",
"load_size": "불러올 키 수",
"mark_color": "표시 색상"
},
"alias": {
"title": "데이터베이스 별칭",
"db": "데이터베이스 인덱스 입력",
"value": "데이터베이스 별칭 입력"
"value": "별칭 입력"
},
"ssl": {
"title": "SSL/TLS",
"enable": "SSL/TLS 활성화",
"allow_insecure": "안전하지 않은 연결 허용",
"sni": "서버(SNI)",
"sni_tip": "(선택) 서버",
"cert_file": "공개키 파일",
"key_file": "개인키 파일",
"sni": "서버 이름(SNI)",
"sni_tip": "(선택) 서버 이름",
"cert_file": "공개 키 파일",
"key_file": "개인 키 파일",
"ca_file": "CA 파일",
"cert_file_tip": "PEM 형식 공개키 파일(Cert)",
"key_file_tip": "PEM 형식 개인키 파일(Key)",
"cert_file_tip": "PEM 형식 공개 키 파일(Cert)",
"key_file_tip": "PEM 형식 개인 키 파일(Key)",
"ca_file_tip": "PEM 형식 CA 파일(CA)"
},
"ssh": {
"enable": "SSH 터널 활성화",
"title": "SSH 터널",
"login_type": "로그인 유형",
"pkfile": "개인키 파일",
"passphrase": "암호구",
"pkfile": "개인 키 파일",
"passphrase": "암호",
"addr_tip": "SSH 주소",
"usr_tip": "SSH 사용자",
"usr_tip": "SSH 사용자 이름",
"pwd_tip": "SSH 비밀번호",
"pkfile_tip": "SSH 개인키 파일 경로",
"passphrase_tip": "(선택) 개인키 암호구"
"pkfile_tip": "SSH 개인 키 파일 경로",
"passphrase_tip": "(선택) SSH 개인 키 암호구"
},
"sentinel": {
"title": "센티널",
"enable": "센티널 노드로 사용",
"master": "마스터 그룹",
"auto_discover": "자동 발견",
"title": "센티널 모드",
"enable": "현재 센티널 노드",
"master": "마스터 그룹 이름",
"auto_discover": "자동 탐색",
"password": "마스터 비밀번호",
"username": "마스터 사용자",
"pwd_tip": "(선택) 마스터 인증 사용자",
"username": "마스터 사용자 이름",
"pwd_tip": "(선택) 마스터 인증 사용자 이름",
"usr_tip": "(선택) 마스터 인증 비밀번호 (Redis > 6.0)"
},
"cluster": {
"title": "클러스터",
"enable": "클러스터 노드로 사용",
"proxy": {
"title": "프록시",
"type_none": "프록시 사용 안함",
"type_system": "시스템 프록시 설정 사용",
"type_custom": "프록시 수동 설정",
"host": "호스트명",
"auth": "프록시 인증",
"usr_tip": "프록시 인증 사용자명",
"pwd_tip": "프록시 인증 비밀번호"
}
"title": "클러스터 모드",
"enable": "현재 클러스터 노드"
},
"group": {
"name": "그룹명",
"rename": "그룹 이름 변경",
"new": "새 그룹"
},
"key": {
"new": "새 키",
"new_name": "새 키명",
"server": "연결",
"db_index": "데이터베이스 인덱스",
"key_expression": "키 패턴",
"affected_key": "영향받는 키",
"show_affected_key": "영향받는 키 보기",
"confirm_delete_key": "{num}개 키를 삭제하시겠습니까?",
"async_delete": "비동기 실행",
"async_delete_title": "결과를 기다리지 않음",
"confirm_flush": "내가 하는 작업을 알고 있습니다!",
"confirm_flush_db": "데이터베이스 플러시를 확인하세요"
},
"delete": {
"success": "\"{key}\"(이)가 삭제되었습니다",
"deleting": "삭제 중",
"doing": "키 삭제 ({index}/{count})",
"completed": "삭제 작업 완료, {success}개 성공, {fail}개 실패"
},
"field": {
"new": "새 필드",
"new_item": "새 항목",
"conflict_handle": "필드 충돌 시",
"overwrite_field": "덮어쓰기",
"ignore_field": "무시",
"insert_type": "삽입 유형",
"append_item": "마지막에 추가",
"prepend_item": "앞에 추가",
"enter_key": "키 입력",
"enter_value": "값 입력",
"enter_field": "필드명 입력",
"enter_elem": "요소 입력",
"enter_member": "멤버 입력",
"enter_score": "점수 입력",
"element": "요소",
"reload_when_succ": "성공 시 즉시 새로고침"
},
"filter": {
"set_key_filter": "키 필터 설정",
"filter_pattern": "패턴",
"filter_pattern_tip": "* 0개 이상 문자 매치, e.g. 'key*'\n? 단일 문자 매치, e.g. 'key?'\n[] 범위 내 단일 문자 매치, e.g. 'key[1-3]'\n\\ 특수문자 이스케이프",
"exact_match_tip": "완전 일치"
},
"export": {
"name": "데이터 내보내기",
"export_expire_title": "만료 시간",
"export_expire": "만료 시간 포함",
"export": "내보내기",
"save_file": "내보내기 경로",
"save_file_tip": "내보낸 파일 저장 경로 선택",
"exporting": "키 내보내기 ({index}/{count})",
"export_completed": "내보내기 완료, {success}개 성공, {fail}개 실패"
},
"import": {
"name": "데이터 가져오기",
"import_expire_title": "만료 시간",
"import": "가져오기",
"reload": "가져온 후 새로고침",
"open_csv_file": "가져올 파일",
"open_csv_file_tip": "가져올 파일 선택",
"conflict_handle": "키 충돌 시",
"conflict_overwrite": "덮어쓰기",
"conflict_ignore": "무시",
"ttl_include": "파일에서 가져오기",
"ttl_ignore": "설정 안함",
"ttl_custom": "직접 설정",
"importing": "키 가져오기 가져옴/덮어씀:{imported} 충돌/실패:{conflict}",
"import_completed": "가져오기 완료, {success}개 성공, {ignored}개 무시됨"
},
"ttl": {
"title": "TTL 업데이트",
"title_batch": "일괄 TTL 업데이트 ({count})",
"quick_set": "빠른 설정",
"success": "모든 키의 TTL이 업데이트되었습니다"
},
"decoder": {
"name": "새 디코더/인코더",
"edit_name": "디코더/인코더 편집",
"new": "새로 만들기",
"decoder": "디코더",
"encoder": "인코더",
"decoder_name": "이름",
"auto": "자동 디코딩",
"decode_path": "디코더 경로",
"encode_path": "인코더 경로",
"path_help": "실행 파일 경로 또는 'sh/php/python' 등의 CLI 별칭",
"args": "인수",
"args_help": "인코딩/디코딩 내용 자리에 [VALUE] 사용, 없으면 끝에 추가됨"
},
"upgrade": {
"title": "새 버전이 있습니다",
"new_version_tip": "새 버전 {ver} 다운로드하시겠습니까?",
"no_update": "최신 버전입니다",
"download_now": "지금 다운로드",
"later": "나중에",
"skip": "이 버전 건너뛰기"
},
"about": {
"source": "소스 코드",
"website": "공식 웹사이트"
"proxy": {
"title": "프록시",
"type_none": "프록시 사용 안함",
"type_system": "시스템 프록시 설정 사용",
"type_custom": "프록시 수동 설정",
"host": "호스트명",
"auth": "인증 사용",
"usr_tip": "프록시 인증 사용자 이름",
"pwd_tip": "프록시 인증 비밀번호"
}
},
"menu": {
"minimise": "최소화",
"maximise": "최대화",
"restore": "복원",
"close": "닫기",
"preferences": "설정",
"help": "도움말",
"user_guide": "사용자 가이드",
"check_update": "업데이트 확인...",
"report_bug": "버그 신고",
"about": "정보"
"group": {
"name": "그룹 이름",
"rename": "그룹 이름 변경",
"new": "새 그룹"
},
"log": {
"title": "실행 로그",
"filter_server": "서버 필터",
"filter_keyword": "키워드 필터",
"clean_log": "로그 비우기",
"confirm_clean_log": "실행 로그를 비우시겠습니까?",
"exec_time": "실행 시간",
"server": "서버",
"cmd": "명령",
"cost_time": "소요 시간",
"refresh": "새로고침"
"key": {
"new": "새 키",
"new_name": "새 키 이름",
"server": "연결",
"db_index": "데이터베이스 인덱스",
"key_expression": "키 패턴",
"affected_key": "영향받는 키",
"show_affected_key": "영향받는 키 표시",
"confirm_delete_key": "{num}개의 키를 삭제하시겠습니까?",
"async_delete": "비동기 실행",
"async_delete_title": "결과를 기다리지 않음",
"confirm_flush": "진행 중인 작업을 알고 있습니다!",
"confirm_flush_db": "데이터베이스 플러시 확인"
},
"status": {
"uptime": "가동 시간",
"connected_clients": "연결 클라이언트",
"total_keys": "전체 키 수",
"memory_used": "사용 메모리",
"server_info": "서버 정보",
"activity_status": "활동 상태",
"act_cmd": "초당 명령 수",
"act_network_input": "네트워크 입력",
"act_network_output": "네트워크 출력",
"client": {
"title": "클라이언트 목록",
"addr": "클라이언트 주소",
"age": "연결 시간 (초)",
"idle": "유휴 시간 (초)",
"db": "데이터베이스"
}
"delete": {
"success": "\"{key}\"가 삭제되었습니다",
"deleting": "삭제 중",
"doing": "키 삭제 중 ({index}/{count})",
"completed": "삭제가 완료되었습니다. 성공: {success}개, 실패: {fail}개"
},
"slog": {
"title": "슬로우 로그",
"limit": "제한",
"filter": "필터",
"exec_time": "실행 시간",
"client": "클라이언트",
"cmd": "명령",
"cost_time": "소요 시간"
"field": {
"new": "새 필드",
"new_item": "새 항목",
"conflict_handle": "필드 충돌 시",
"overwrite_field": "덮어쓰기",
"ignore_field": "무시",
"insert_type": "삽입 유형",
"append_item": "추가",
"prepend_item": "앞에 추가",
"enter_key": "키 입력",
"enter_value": "값 입력",
"enter_field": "필드 이름 입력",
"enter_elem": "요소 입력",
"enter_member": "멤버 입력",
"enter_score": "점수 입력",
"element": "요소",
"reload_when_succ": "성공하면 즉시 새로고침"
},
"monitor": {
"title": "명령 모니터",
"actions": "작업",
"warning": "명령 모니터링은 서버 차단을 유발할 수 있으므로, 운영 서버에선 주의해서 사용하세요.",
"start": "시작",
"stop": "정지",
"search": "검색",
"copy_log": "로그 복사",
"save_log": "로그 저장",
"clean_log": "로그 비우기",
"always_show_last": "최신 계속 보기"
"filter": {
"set_key_filter": "키 필터 설정",
"filter_pattern": "패턴",
"filter_pattern_tip": "* 0개 이상의 문자 일치, 예) 'key*'\n? 단일 문자 일치, 예) 'key?'\n[] 범위 일치, 예) 'key[1-3]'\n\\ 특수문자 이스케이프",
"exact_match_tip": "완전 일치"
},
"pubsub": {
"title": "Pub/Sub",
"publish": "발행",
"subscribe": "구독 시작",
"unsubscribe": "구독 취소",
"clear": "메세지 지우기",
"time": "시간",
"filter": "필터",
"channel": "채널",
"message": "메세지",
"receive_message": "{total}개 메세지 수신됨",
"always_show_last": "최신 계속 보기"
"export": {
"name": "데이터 내보내기",
"export_expire_title": "만료 시간",
"export_expire": "만료 시간 포함",
"export": "내보내기",
"save_file": "내보내기 경로",
"save_file_tip": "내보낼 파일 저장 경로 선택",
"exporting": "키 내보내는 중 ({index}/{count})",
"export_completed": "내보내기가 완료되었습니다. 성공: {success}개, 실패: {fail}개"
},
"import": {
"name": "데이터 가져오기",
"import_expire_title": "만료 시간",
"import": "가져오기",
"reload": "가져오기 후 새로고침",
"open_csv_file": "가져올 파일",
"open_csv_file_tip": "가져올 파일 선택",
"conflict_handle": "키 충돌 시",
"conflict_overwrite": "덮어쓰기",
"conflict_ignore": "무시",
"ttl_include": "파일에서 가져오기",
"ttl_ignore": "설정 안함",
"ttl_custom": "직접 설정",
"importing": "키 가져오는 중 가져오기/덮어쓰기:{imported} 충돌/실패:{conflict}",
"import_completed": "가져오기가 완료되었습니다. 성공: {success}개, 무시: {ignored}개"
},
"ttl": {
"title": "TTL 업데이트",
"title_batch": "TTL 일괄 업데이트 ({count})",
"quick_set": "빠른 설정",
"success": "모든 키의 TTL이 업데이트되었습니다"
},
"decoder": {
"name": "새 디코더/인코더",
"edit_name": "디코더/인코더 편집",
"new": "새로 만들기",
"decoder": "디코더",
"encoder": "인코더",
"decoder_name": "이름",
"auto": "자동 디코딩",
"decode_path": "디코더 경로",
"encode_path": "인코더 경로",
"path_help": "실행 파일 경로 또는 sh/php/python과 같은 CLI 별칭",
"args": "인수",
"args_help": "[VALUE]를 인코딩/디코딩 내용 자리 표시자로 사용하세요. 자리 표시자가 없으면 끝에 추가됩니다."
},
"upgrade": {
"title": "새 버전 사용 가능",
"new_version_tip": "새 버전 {ver}이 있습니다. 지금 다운로드하시겠습니까?",
"no_update": "최신 버전입니다",
"download_now": "지금 다운로드",
"later": "나중에",
"skip": "이 버전 건너뛰기"
},
"welcome": {
"title": "Tiny RDM에 오신 것을 환영합니다!",
"content": "더 나은 사용자 경험을 제공하기 위해 Tiny RDM은 일부 익명 데이터를 수집하여 소프트웨어를 최적화하고 사용자 경험을 개선하는 데 사용합니다. 이는 개인 정보와는 무관함을 알려드립니다.\n\n만약 우려되는 점이 있다면 설정에서 이 데이터 수집 기능을 언제든 끌 수 있습니다. 문의 사항이 있으면 개발자에게 연락하시기 바랍니다. Tiny RDM이 좋은 도우미가 되길 바랍니다!",
"accept": "개선에 동의",
"reject": "거부"
},
"about": {
"source": "소스 코드",
"website": "공식 웹사이트"
}
},
"menu": {
"minimise": "최소화",
"maximise": "최대화",
"restore": "복원",
"close": "닫기",
"preferences": "설정",
"help": "도움말",
"user_guide": "사용자 가이드",
"check_update": "업데이트 확인...",
"report_bug": "버그 신고",
"about": "정보"
},
"log": {
"title": "실행 로그",
"filter_server": "서버 필터링",
"filter_keyword": "키워드 필터링",
"clean_log": "로그 지우기",
"confirm_clean_log": "실행 로그를 지우시겠습니까?",
"exec_time": "실행 시간",
"server": "서버",
"cmd": "명령",
"cost_time": "소요 시간",
"refresh": "새로고침"
},
"status": {
"uptime": "가동 시간",
"connected_clients": "클라이언트 수",
"total_keys": "키 수",
"memory_used": "메모리 사용량",
"server_info": "서버 정보",
"activity_status": "활동 현황",
"act_cmd": "명령/초",
"act_network_input": "네트워크 입력",
"act_network_output": "네트워크 출력",
"client": {
"title": "클라이언트 목록",
"addr": "클라이언트 주소",
"age": "시간(초)",
"idle": "유휴 시간(초)",
"db": "데이터베이스"
}
},
"slog": {
"title": "슬로우 로그",
"limit": "제한",
"filter": "필터",
"exec_time": "시간",
"client": "클라이언트",
"cmd": "명령",
"cost_time": "소요 시간"
},
"monitor": {
"title": "명령 모니터링",
"actions": "작업",
"warning": "명령 모니터링은 서버 차단을 유발할 수 있으므로 실서버에서는 주의해서 사용하세요.",
"start": "시작",
"stop": "정지",
"search": "검색",
"copy_log": "로그 복사",
"save_log": "로그 저장",
"clean_log": "로그 지우기",
"always_show_last": "최신 항목 계속 표시"
},
"pubsub": {
"title": "Pub/Sub",
"publish": "발행",
"subscribe": "구독",
"unsubscribe": "구독 취소",
"clear": "메시지 지우기",
"time": "시간",
"filter": "필터",
"channel": "채널",
"message": "메시지",
"receive_message": "{total}개의 메시지를 받았습니다",
"always_show_last": "최신 항목 계속 표시"
}
}

View File

@ -46,7 +46,9 @@
"key_icon_style2": "Ponto",
"key_icon_style3": "Comum",
"update": "Atualizar",
"auto_check_update": "Verificar atualizações automaticamente"
"auto_check_update": "Verificar atualizações automaticamente",
"privacy": "Política de Privacidade",
"allow_track": "Permitir a coleta de dados anônimos"
},
"editor": {
"name": "Editor",
@ -382,6 +384,12 @@
"later": "Depois",
"skip": "Ignorar Esta Versão"
},
"welcome": {
"title": "Bem-vindo ao Tiny RDM!",
"content": "Para fornecer uma melhor experiência ao usuário, o Tiny RDM coleta alguns dados anônimos para ajudar a otimizar o software e melhorar a experiência do usuário. Fique tranquilo, isso não envolve suas informações de privacidade pessoal.\n\nSe você tiver alguma preocupação, pode desativar esse recurso de coleta de dados a qualquer momento indo em Preferências. Se tiver alguma dúvida, sinta-se à vontade para entrar em contato com o desenvolvedor. Espero que o Tiny RDM possa se tornar um assistente útil para você!",
"accept": "Help Improve",
"reject": "Reject"
},
"about": {
"source": "Código Fonte",
"website": "Site Oficial"

View File

@ -0,0 +1,474 @@
{
"name": "Русский язык",
"common": {
"confirm": "Подтвердить",
"cancel": "Отменить",
"success": "Успех",
"warning": "Предупреждение",
"error": "Ошибка",
"save": "Сохранить",
"update": "Обновить",
"none": "Нет",
"second": "Секунда(ы)",
"minute": "Минута(ы)",
"hour": "Час(ы)",
"day": "День(и)",
"unit_day": "д",
"unit_hour": "ч",
"unit_minute": "м",
"unit_second": "с",
"all": "Все",
"key": "Ключ",
"value": "Значение",
"field": "Поле",
"score": "Счёт",
"index": "Позиция"
},
"preferences": {
"name": "Настройки",
"restore_defaults": "Восстановить настройки по умолчанию",
"font_tip": "Поддерживается множественный выбор. Если установленный шрифт не указан в списке, введите его вручную.",
"general": {
"name": "Общие",
"theme": "Тема",
"theme_light": "Светлая",
"theme_dark": "Тёмная",
"theme_auto": "Авто",
"language": "Язык",
"system_lang": "Использовать язык системы",
"font": "Шрифт",
"font_tip": "Выберите или введите название шрифта",
"font_size": "Размер шрифта",
"scan_size": "Размер по умолчанию для SCAN",
"key_icon_style": "Стиль значка ключа",
"key_icon_style0": "Компактный",
"key_icon_style1": "Полное название",
"key_icon_style2": "Точка",
"key_icon_style3": "Обычный",
"update": "Обновить",
"auto_check_update": "Автоматически проверять обновления",
"privacy": "Конфиденциальность",
"allow_track": "Разрешить сбор анонимных данных"
},
"editor": {
"name": "Редактор",
"show_linenum": "Показывать номера строк",
"show_folding": "Включить сворачивание кода",
"drop_text": "Разрешить перетаскивание текста",
"links": "Поддержка ссылок"
},
"cli": {
"name": "Командная строка",
"cursor_style": "Стиль курсора",
"cursor_style_block": "Блок",
"cursor_style_underline": "Подчёркнутый",
"cursor_style_bar": "Линия"
},
"decoder": {
"name": "Пользовательский декодер",
"new": "Новый декодер",
"decoder_name": "Название",
"cmd_preview": "Предпросмотр",
"status": "Статус",
"auto_enabled": "Автодекодирование включено",
"help": "Помощь"
}
},
"interface": {
"new_conn": "Добавить соединение",
"new_group": "Добавить группу",
"disconnect_all": "Отключить все",
"status": "Статус",
"filter": "Фильтр",
"sort_conn": "Сортировать соединения",
"new_conn_title": "Новое соединение",
"open_db": "Открыть базу данных",
"close_db": "Закрыть базу данных",
"filter_key": "Фильтр ключей",
"disconnect": "Отключить",
"dup_conn": "Дублировать соединение",
"remove_conn": "Удалить соединение",
"edit_conn": "Редактировать соединение",
"edit_conn_group": "Редактировать группу",
"rename_conn_group": "Переименовать группу",
"remove_conn_group": "Удалить группу",
"import_conn": "Импортировать соединения...",
"export_conn": "Экспортировать соединения...",
"ttl": "TTL",
"forever": "Навсегда",
"rename_key": "Переименовать ключ",
"delete_key": "Удалить ключ",
"batch_delete_key": "Пакетное удаление ключей",
"import_key": "Импортировать ключи",
"flush_db": "Очистить базу данных",
"check_mode": "Режим выбора",
"quit_check_mode": "Выйти из режима выбора",
"delete_checked": "Удалить выбранные",
"export_checked": "Экспортировать выбранные",
"ttl_checked": "Обновить TTL для выбранных",
"copy_value": "Копировать значение",
"edit_value": "Редактировать значение",
"save_update": "Сохранить изменения",
"score_filter_tip": "Поддерживаются операторы: \n= равно\n!= не равно\n> больше\n>= больше или равно\n< меньше\n<= меньше или равно\nНапример, >3 для значений больше 3",
"add_row": "Вставить строку",
"edit_row": "Редактировать строку",
"delete_row": "Удалить строку",
"fullscreen": "Полноэкранный режим",
"offscreen": "Выйти из полноэкранного режима",
"pin_edit": "Закрепить (не закрывать после сохранения)",
"unpin_edit": "Открепить",
"search": "Поиск",
"full_search": "Полнотекстовый поиск",
"full_search_result": "Содержимое соответствует '{pattern}'",
"filter_field": "Фильтр полей",
"filter_value": "Фильтр значений",
"length": "Длина",
"entries": "Записи",
"memory_usage": "Использование памяти",
"view_as": "Вид",
"decode_with": "Декодировать/Распаковать",
"custom_decoder": "Новый пользовательский декодер",
"reload": "Перезагрузить",
"reload_disable": "Перезагрузить после полной загрузки",
"auto_refresh": "Автообновление",
"refresh_interval": "Интервал обновления",
"open_connection": "Открыть соединение",
"copy_path": "Копировать путь",
"copy_key": "Копировать ключ",
"save_value_succ": "Значение сохранено!",
"copy_succ": "Скопировано в буфер обмена!",
"binary_key": "Двоичное имя ключа",
"remove_key": "Удалить ключ",
"new_key": "Новый ключ",
"load_more": "Загрузить больше ключей",
"load_all": "Загрузить все оставшиеся ключи",
"load_more_entries": "Загрузить больше",
"load_all_entries": "Загрузить все",
"more_action": "Больше действий",
"nonexist_tab_content": "Выбранный ключ не существует или не выбран. Попробуйте обновить.",
"empty_server_content": "Выберите и откройте соединение с левой панели",
"empty_server_list": "Нет добавленных серверов Redis",
"action": "Действие",
"type": "Тип",
"cli_welcome": "Добро пожаловать в консоль Redis Tiny RDM",
"retrieving_version": "Проверка обновлений",
"sub_tab": {
"status": "Статус",
"key_detail": "Детали ключа",
"cli": "Консоль",
"slow_log": "Медленный лог",
"cmd_monitor": "Мониторинг команд",
"pub_message": "Публикация/Подписка"
}
},
"ribbon": {
"server": "Сервер",
"browser": "Браузер данных",
"log": "Лог",
"wechat_official": "Официальный аккаунт WeChat",
"follow_x": "Подписаться на \uD835\uDD4F",
"github": "Github"
},
"dialogue": {
"close_confirm": "Закрыть это соединение ({name})?",
"edit_close_confirm": "Перед редактированием закройте соответствующие соединения. Продолжить?",
"opening_connection": "Открытие соединения...",
"interrupt_connection": "Отменить",
"remove_tip": "{type} \"{name}\" будет удален(а/о)",
"remove_group_tip": "Группа \"{name}\" и все её соединения будут удалены",
"rename_binary_key_fail": "Переименование двоичного ключа не поддерживается",
"handle_succ": "Успешно!",
"handle_cancel": "Операция отменена.",
"reload_succ": "Перезагружено!",
"field_required": "Это поле обязательно для заполнения",
"spec_field_required": "\"{key}\" требуется",
"illegal_characters": "Содержит недопустимые символы",
"connection": {
"new_title": "Новое соединение",
"edit_title": "Редактировать соединение",
"general": "Общие",
"no_group": "Без группы",
"group": "Группа",
"conn_name": "Название",
"addr": "Адрес",
"usr": "Имя пользователя",
"pwd": "Пароль",
"name_tip": "Название соединения",
"addr_tip": "Адрес сервера Redis",
"sock_tip": "Unix-сокет файл Redis",
"usr_tip": "(Опционально) Имя пользователя для авторизации",
"pwd_tip": "(Опционально) Пароль для авторизации (Redis > 6.0)",
"test": "Проверить соединение",
"test_succ": "Успешно подключено к серверу Redis",
"test_fail": "Не удалось подключиться",
"parse_url_clipboard": "Распарсить URL из буфера обмена",
"parse_pass": "Redis URL распарсен: {url}",
"parse_fail": "Не удалось распарсить Redis URL: {reason}",
"advn": {
"title": "Дополнительно",
"filter": "Фильтр ключей по умолчанию",
"filter_tip": "Шаблон для фильтрации загруженных ключей",
"separator": "Разделитель ключей",
"separator_tip": "Разделитель сегментов пути ключа",
"conn_timeout": "Тайм-аут соединения",
"exec_timeout": "Тайм-аут выполнения",
"dbfilter_type": "Фильтр баз данных",
"dbfilter_all": "Показать все",
"dbfilter_show": "Показать выбранные",
"dbfilter_hide": "Скрыть выбранные",
"dbfilter_show_title": "Базы данных для показа",
"dbfilter_hide_title": "Базы данных для скрытия",
"dbfilter_input": "Введите индекс базы данных",
"dbfilter_input_tip": "Нажмите Enter для подтверждения",
"key_view": "Вид ключей по умолчанию",
"key_view_tree": "Древовидный",
"key_view_list": "Списком",
"load_size": "Ключей за загрузку",
"mark_color": "Цвет маркера"
},
"alias": {
"title": "Псевдонимы баз данных",
"db": "Введите индекс базы данных",
"value": "Введите псевдоним"
},
"ssl": {
"title": "SSL/TLS",
"enable": "Включить SSL/TLS",
"allow_insecure": "Разрешить небезопасные соединения",
"sni": "Имя сервера (SNI)",
"sni_tip": "(Опционально) Имя сервера",
"cert_file": "Файл открытого ключа",
"key_file": "Файл закрытого ключа",
"ca_file": "Файл CA",
"cert_file_tip": "Файл открытого ключа в формате PEM (Cert)",
"key_file_tip": "Файл закрытого ключа в формате PEM (Key)",
"ca_file_tip": "Файл авторитета сертификации в формате PEM (CA)"
},
"ssh": {
"enable": "Включить SSH-туннель",
"title": "SSH-туннель",
"login_type": "Тип входа",
"pkfile": "Файл закрытого ключа",
"passphrase": "Парольная фраза",
"addr_tip": "Адрес SSH-сервера",
"usr_tip": "Имя пользователя SSH",
"pwd_tip": "Пароль SSH",
"pkfile_tip": "Путь к файлу закрытого ключа SSH",
"passphrase_tip": "(Опционально) Парольная фраза для закрытого ключа"
},
"sentinel": {
"title": "Сентинель",
"enable": "В качестве узла Сентинеля",
"master": "Имя группы мастера",
"auto_discover": "Автоопределение",
"password": "Пароль мастера",
"username": "Имя пользователя мастера",
"pwd_tip": "(Опционально) Имя пользователя мастера для авторизации",
"usr_tip": "(Опционально) Пароль мастера для авторизации (Redis > 6.0)"
},
"cluster": {
"title": "Кластер",
"enable": "В качестве узла кластера"
},
"proxy": {
"title": "Прокси",
"type_none": "Без прокси",
"type_system": "Прокси системы",
"type_custom": "Ручная настройка прокси",
"host": "Имя хоста",
"auth": "Авторизация прокси",
"usr_tip": "Имя пользователя для авторизации прокси",
"pwd_tip": "Пароль для авторизации прокси"
}
},
"group": {
"name": "Имя группы",
"rename": "Переименовать группу",
"new": "Новая группа"
},
"key": {
"new": "Новый ключ",
"new_name": "Новое имя ключа",
"server": "Соединение",
"db_index": "Индекс базы данных",
"key_expression": "Шаблон ключей",
"affected_key": "Затронутые ключи",
"show_affected_key": "Показать затронутые ключи",
"confirm_delete_key": "Подтвердить удаление {num} ключ(ей/ей)",
"async_delete": "Асинхронное выполнение",
"async_delete_title": "Не ждать результата",
"confirm_flush": "Я знаю, что делаю!",
"confirm_flush_db": "Подтвердить очистку базы данных"
},
"delete": {
"success": "\"{key}\" удален(а/о)",
"deleting": "Удаление",
"doing": "Удаление ключа ({index}/{count})",
"completed": "Удаление завершено, {success} успешно, {fail} с ошибкой"
},
"field": {
"new": "Новое поле",
"new_item": "Новый элемент",
"conflict_handle": "При конфликте полей",
"overwrite_field": "Перезаписать",
"ignore_field": "Пропустить",
"insert_type": "Тип вставки",
"append_item": "Добавить в конец",
"prepend_item": "Добавить в начало",
"enter_key": "Введите ключ",
"enter_value": "Введите значение",
"enter_field": "Введите имя поля",
"enter_elem": "Введите элемент",
"enter_member": "Введите элемент",
"enter_score": "Введите счёт",
"element": "Элемент",
"reload_when_succ": "Перезагрузить сразу после успеха"
},
"filter": {
"set_key_filter": "Установить фильтр ключей",
"filter_pattern": "Шаблон",
"filter_pattern_tip": "* соответствует 0 или более символов, напр. 'key*'\n? соответствует одному символу, напр. 'key?'\n[] соответствует диапазону, напр. 'key[1-3]'\n\\ экранирует спецсимволы",
"exact_match_tip": "Точное совпадение"
},
"export": {
"name": "Экспорт данных",
"export_expire_title": "Срок истечения",
"export_expire": "Включить срок истечения",
"export": "Экспорт",
"save_file": "Путь для экспорта",
"save_file_tip": "Выберите путь для сохранения экспортируемого файла",
"exporting": "Экспорт ключей ({index}/{count})",
"export_completed": "Экспорт завершен, {success} успешно, {fail} с ошибкой"
},
"import": {
"name": "Импорт данных",
"import_expire_title": "Срок истечения",
"reload": "Перезагрузить после импорта",
"import": "Импорт",
"open_csv_file": "Импортировать файл",
"open_csv_file_tip": "Выберите файл для импорта",
"conflict_handle": "При конфликте ключей",
"conflict_overwrite": "Перезаписать",
"conflict_ignore": "Пропустить",
"ttl_include": "Импортировать из файла",
"ttl_ignore": "Не устанавливать",
"ttl_custom": "Пользовательское",
"importing": "Импорт ключей импортировано/перезаписано:{imported} конфликтов/ошибок:{conflict}",
"import_completed": "Импорт завершен, {success} успешно, {ignored} пропущено"
},
"ttl": {
"title": "Обновить TTL",
"title_batch": "Пакетное обновление TTL ({count})",
"quick_set": "Быстрая установка",
"success": "TTL обновлен для всех ключей"
},
"decoder": {
"name": "Новый декодер/энкодер",
"edit_name": "Редактировать декодер/энкодер",
"new": "Новый",
"decoder": "Декодер",
"encoder": "Энкодер",
"decoder_name": "Название",
"auto": "Автодекодирование",
"decode_path": "Путь декодера",
"encode_path": "Путь энкодера",
"path_help": "Путь к исполняемому файлу или алиасу cli, например 'sh/php/python'",
"args": "Аргументы",
"args_help": "Используйте [VALUE] в качестве заменителя для кодирования/декодирования. Если заменитель не указан, содержимое будет добавлено в конец."
},
"upgrade": {
"title": "Доступна новая версия",
"new_version_tip": "Доступна новая версия {ver}, загрузить сейчас?",
"no_update": "У вас установлена последняя версия",
"download_now": "Загрузить сейчас",
"later": "Позже",
"skip": "Пропустить эту версию"
},
"welcome": {
"title": "Добро пожаловать в Tiny RDM",
"content": "Для предоставления лучшего пользовательского опыта Tiny RDM собирает некоторые анонимные данные, чтобы помочь оптимизировать программное обеспечение и улучшить пользовательский опыт. Не беспокойтесь, это не будет затрагивать вашу личную конфиденциальную информацию.\n\nЕсли у вас есть какие-либо опасения, вы можете в любое время отключить сбор данных, перейдя в «Настройки». Если у вас есть какие-либо вопросы, обращайтесь к разработчику. Надеюсь, Tiny RDM станет вашим полезным помощником!",
"accept": "Помочь улучшить",
"reject": "Отклонить"
},
"about": {
"source": "Исходный код",
"website": "Официальный сайт"
}
},
"menu": {
"minimise": "Свернуть",
"maximise": "Развернуть",
"restore": "Восстановить",
"close": "Закрыть",
"preferences": "Настройки",
"help": "Помощь",
"user_guide": "Руководство пользователя",
"check_update": "Проверить обновления...",
"report_bug": "Сообщить об ошибке",
"about": "О программе"
},
"log": {
"title": "Журнал запуска",
"filter_server": "Фильтр сервера",
"filter_keyword": "Фильтр ключевых слов",
"clean_log": "Очистить журнал",
"confirm_clean_log": "Подтвердите очистку журнала запуска",
"exec_time": "Время выполнения",
"server": "Сервер",
"cmd": "Команда",
"cost_time": "Затраченное время",
"refresh": "Обновить"
},
"status": {
"uptime": "Uptime",
"connected_clients": "Клиенты",
"total_keys": "Ключи",
"memory_used": "Память",
"server_info": "Информация о сервере",
"activity_status": "Активность",
"act_cmd": "Команд/сек",
"act_network_input": "Входящий трафик",
"act_network_output": "Исходящий трафик",
"client": {
"title": "Список клиентов",
"addr": "Адрес клиента",
"age": "Время (сек)",
"idle": "Простой (сек)",
"db": "База данных"
}
},
"slog": {
"title": "Медленный журнал",
"limit": "Лимит",
"filter": "Фильтр",
"exec_time": "Время",
"client": "Клиент",
"cmd": "Команда",
"cost_time": "Затраченное время"
},
"monitor": {
"title": "Мониторинг команд",
"actions": "Действия",
"warning": "Мониторинг команд может вызвать блокировку сервера, используйте с осторожностью на производственных серверах.",
"start": "Старт",
"stop": "Стоп",
"search": "Поиск",
"copy_log": "Копировать журнал",
"save_log": "Сохранить журнал",
"clean_log": "Очистить журнал",
"always_show_last": "Всегда показывать последние"
},
"pubsub": {
"title": "Публикация/Подписка",
"publish": "Опубликовать",
"subscribe": "Подписаться",
"unsubscribe": "Отписаться",
"clear": "Очистить сообщения",
"time": "Время",
"filter": "Фильтр",
"channel": "Канал",
"message": "Сообщение",
"receive_message": "Получено сообщений: {total}",
"always_show_last": "Всегда показывать последние"
}
}

View File

@ -46,7 +46,9 @@
"key_icon_style2": "圆点类型",
"key_icon_style3": "通用图标",
"update": "更新",
"auto_check_update": "自动检查更新"
"auto_check_update": "自动检查更新",
"privacy": "隐私策略",
"allow_track": "允许收集匿名数据"
},
"editor": {
"name": "编辑器",
@ -382,6 +384,12 @@
"later": "稍后提醒我",
"skip": "忽略本次更新"
},
"welcome": {
"title": "欢迎使用Tiny RDM",
"content": "为了提供更好的用户体验Tiny RDM会收集一些匿名的数据以帮助优化软件和改进用户体验请放心这不会涉及到您的个人隐私信息。\n\n如果您对此有任何顾虑可以随时前往\"偏好设置\"中关闭此项数据收集功能。有任何问题可联系开发者希望Tiny RDM可以成为您的好帮手",
"accept": "帮助改进",
"reject": "不接受"
},
"about": {
"source": "源码地址",
"website": "官方网站"

View File

@ -46,7 +46,9 @@
"key_icon_style2": "點類型",
"key_icon_style3": "通用圖示",
"update": "更新",
"auto_check_update": "自動檢查更新"
"auto_check_update": "自動檢查更新",
"privacy": "隱私權政策",
"allow_track": "允許收集匿名數據"
},
"editor": {
"name": "編輯器",
@ -382,6 +384,12 @@
"later": "稍後提醒我",
"skip": "忽略本次更新"
},
"welcome": {
"title": "歡迎使用Tiny RDM",
"content": "為了提供更好的使用者體驗Tiny RDM 會收集一些匿名的數據,以幫助最佳化軟體和改進使用者體驗,請放心這不會涉及到您的個人隱私資訊。\n\n如果您對此有任何顧慮可以隨時前往\"偏好設定\"中關閉此項數據收集功能。有任何問題可聯繫開發者希望Tiny RDM可以成為您的好幫手",
"accept": "幫助改進",
"reject": "不接受"
},
"about": {
"source": "源碼地址",
"website": "官方網站"

View File

@ -467,16 +467,30 @@ const useBrowserStore = defineStore('browser', {
* @param {string} [decode]
* @param {string} [format]
* @param {string} [matchPattern]
* @param {boolean} [showLoading]
* @return {Promise<void>}
*/
async reloadKey({ server, db, key, decode, format, matchPattern }) {
async reloadKey({ server, db, key, decode, format, matchPattern, showLoading = true }) {
const tab = useTabStore()
try {
tab.updateLoading({ server, db, loading: true })
if (showLoading) {
tab.updateLoading({ server, db, loading: true })
}
await this.loadKeySummary({ server, db, key, clearValue: true })
await this.loadKeyDetail({ server, db, key, decode, format, matchPattern, reset: true })
await this.loadKeyDetail({
server,
db,
key,
decode,
format,
matchPattern,
reset: true,
showLoading: false,
})
} finally {
tab.updateLoading({ server, db, loading: false })
if (showLoading) {
tab.updateLoading({ server, db, loading: false })
}
}
},
@ -490,16 +504,19 @@ const useBrowserStore = defineStore('browser', {
* @param {string} [matchPattern]
* @param {boolean} [reset]
* @param {boolean} [full]
* @param {boolean} [showLoading]
* @return {Promise<void>}
*/
async loadKeyDetail({ server, db, key, format, decode, matchPattern, reset, full }) {
async loadKeyDetail({ server, db, key, format, decode, matchPattern, reset, full, showLoading = true }) {
const tab = useTabStore()
const serverInst = this.servers[server]
if (serverInst == null) {
return
}
try {
tab.updateLoading({ server, db, loading: true })
if (showLoading) {
tab.updateLoading({ server, db, loading: true })
}
const [storeFormat, storeDecode] = serverInst.getDecodeHistory(key, db)
const { data, success, msg } = await GetKeyDetail({
server,
@ -537,7 +554,9 @@ const useBrowserStore = defineStore('browser', {
$message.error('load key detail fail:' + msg)
}
} finally {
tab.updateLoading({ server, db, loading: false })
if (showLoading) {
tab.updateLoading({ server, db, loading: false })
}
}
},

View File

@ -35,6 +35,7 @@ const usePreferencesStore = defineStore('preferences', {
*/
state: () => ({
behavior: {
welcomed: false,
asideWidth: 300,
windowWidth: 0,
windowHeight: 0,
@ -52,6 +53,7 @@ const usePreferencesStore = defineStore('preferences', {
useSysProxyHttp: false,
checkUpdate: true,
skipVersion: '',
allowTrack: true,
},
editor: {
font: '',
@ -445,6 +447,12 @@ const usePreferencesStore = defineStore('preferences', {
return true
},
setAsWelcomed(acceptTrack) {
this.behavior.welcomed = true
this.general.allowTrack = acceptTrack
this.savePreferences()
},
async checkForUpdate(manual = false) {
let msgRef = null
if (manual) {

View File

@ -0,0 +1,46 @@
let inited = false
let allow = false
/**
* load umami analytics module
* @param {boolean} allowTrack
* @return {Promise<void>}
*/
export const loadModule = async (allowTrack = true) => {
allow = allowTrack !== false
await new Promise((resolve, reject) => {
const script = document.createElement('script')
script.setAttribute('src', 'https://analytics.tinycraft.cc/script.js')
script.setAttribute('data-website-id', 'ad6de51d-1e27-44a5-958d-319679c56aec')
script.setAttribute('data-cache', 'true')
script.setAttribute('data-auto-track', allowTrack !== false ? 'true' : 'false')
script.onload = () => {
inited = true
resolve()
}
script.onerror = () => {
inited = false
reject()
}
document.body.appendChild(script)
})
}
const enable = () => {
return inited && allow && umami
}
export const enableTrack = (enable) => {
allow = enable
}
export const trackEvent = async (event, data) => {
if (enable() || event === 'startup') {
umami.track(({ website, language }) => ({
language,
website,
name: event,
data,
}))
}
}

View File

@ -105,7 +105,7 @@ func main() {
TitleBar: mac.TitleBarHiddenInset(),
About: &mac.AboutInfo{
Title: "Tiny RDM " + version,
Message: "A modern lightweight cross-platform Redis desktop client.\n\nCopyright © 2023",
Message: "A modern lightweight cross-platform Redis desktop client.\n\nCopyright © 2024",
Icon: icon,
},
WebviewIsTransparent: false,

View File

@ -14,7 +14,7 @@
"companyName": "Tiny Craft",
"productName": "Tiny RDM",
"productVersion": "1.0.0",
"copyright": "Copyright © 2023",
"copyright": "Copyright © 2024",
"comments": "Tiny Redis Desktop Manager"
}
}