nixamp 0.27.3 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/backtoschool/dist/assets/ar-DK3LI2hP.js +1 -0
  2. package/backtoschool/dist/assets/cs-C9cckHFh.js +1 -0
  3. package/backtoschool/dist/assets/da-BpNIZAZo.js +1 -0
  4. package/backtoschool/dist/assets/de-C1DX_kDk.js +1 -0
  5. package/backtoschool/dist/assets/es-bymdOEnB.js +1 -0
  6. package/backtoschool/dist/assets/fi-p1DAJXf3.js +1 -0
  7. package/backtoschool/dist/assets/fr-w1qH9bbD.js +1 -0
  8. package/backtoschool/dist/assets/hi-DnZJakpY.js +1 -0
  9. package/backtoschool/dist/assets/hu-N7uSyLAk.js +1 -0
  10. package/backtoschool/dist/assets/id-CX3MVU3E.js +1 -0
  11. package/backtoschool/dist/assets/index-4LdMSur6.js +93 -0
  12. package/backtoschool/dist/assets/{index-Bot4FEXQ.css → index-D06NfY1L.css} +1 -1
  13. package/backtoschool/dist/assets/it-CQ0H28FI.js +1 -0
  14. package/backtoschool/dist/assets/nl-DJqCLHMq.js +1 -0
  15. package/backtoschool/dist/assets/ru-Rk2yagke.js +1 -0
  16. package/backtoschool/dist/assets/sv-1r9eOl4-.js +1 -0
  17. package/backtoschool/dist/assets/uk-CrRsLNHV.js +1 -0
  18. package/backtoschool/dist/assets/vi-B5kxrjP7.js +1 -0
  19. package/backtoschool/dist/assets/zh-BB_S8QpG.js +1 -0
  20. package/backtoschool/dist/index.html +44 -43
  21. package/dist/admin.js +5 -4
  22. package/dist/i18n.d.ts +26 -0
  23. package/dist/i18n.js +81 -0
  24. package/dist/locales/ar.d.ts +201 -0
  25. package/dist/locales/ar.js +200 -0
  26. package/dist/locales/cs.d.ts +201 -0
  27. package/dist/locales/cs.js +200 -0
  28. package/dist/locales/da.d.ts +201 -0
  29. package/dist/locales/da.js +200 -0
  30. package/dist/locales/de.d.ts +201 -0
  31. package/dist/locales/de.js +200 -0
  32. package/dist/locales/en.d.ts +201 -0
  33. package/dist/locales/en.js +201 -0
  34. package/dist/locales/es.d.ts +201 -0
  35. package/dist/locales/es.js +200 -0
  36. package/dist/locales/fi.d.ts +201 -0
  37. package/dist/locales/fi.js +200 -0
  38. package/dist/locales/fr.d.ts +201 -0
  39. package/dist/locales/fr.js +200 -0
  40. package/dist/locales/hi.d.ts +201 -0
  41. package/dist/locales/hi.js +200 -0
  42. package/dist/locales/hu.d.ts +201 -0
  43. package/dist/locales/hu.js +200 -0
  44. package/dist/locales/id.d.ts +201 -0
  45. package/dist/locales/id.js +200 -0
  46. package/dist/locales/it.d.ts +201 -0
  47. package/dist/locales/it.js +200 -0
  48. package/dist/locales/nl.d.ts +201 -0
  49. package/dist/locales/nl.js +200 -0
  50. package/dist/locales/ru.d.ts +201 -0
  51. package/dist/locales/ru.js +200 -0
  52. package/dist/locales/sv.d.ts +201 -0
  53. package/dist/locales/sv.js +200 -0
  54. package/dist/locales/uk.d.ts +201 -0
  55. package/dist/locales/uk.js +200 -0
  56. package/dist/locales/vi.d.ts +201 -0
  57. package/dist/locales/vi.js +200 -0
  58. package/dist/locales/zh.d.ts +201 -0
  59. package/dist/locales/zh.js +200 -0
  60. package/dist/main.js +26 -12
  61. package/dist/ui-aliases.d.ts +4 -0
  62. package/dist/ui-aliases.js +41 -0
  63. package/dist/ui-languages.d.ts +62 -0
  64. package/dist/ui-languages.js +32 -0
  65. package/package.json +1 -1
  66. package/src/admin.ts +5 -4
  67. package/src/i18n.ts +74 -0
  68. package/src/locales/ar.ts +201 -0
  69. package/src/locales/cs.ts +201 -0
  70. package/src/locales/da.ts +201 -0
  71. package/src/locales/de.ts +201 -0
  72. package/src/locales/en.ts +201 -0
  73. package/src/locales/es.ts +201 -0
  74. package/src/locales/fi.ts +201 -0
  75. package/src/locales/fr.ts +201 -0
  76. package/src/locales/hi.ts +201 -0
  77. package/src/locales/hu.ts +201 -0
  78. package/src/locales/id.ts +201 -0
  79. package/src/locales/it.ts +201 -0
  80. package/src/locales/nl.ts +201 -0
  81. package/src/locales/ru.ts +201 -0
  82. package/src/locales/sv.ts +201 -0
  83. package/src/locales/uk.ts +201 -0
  84. package/src/locales/vi.ts +201 -0
  85. package/src/locales/zh.ts +201 -0
  86. package/src/main.ts +25 -12
  87. package/src/ui-aliases.ts +42 -0
  88. package/src/ui-languages.ts +31 -0
  89. package/web/dist/assets/ar-DK3LI2hP.js +1 -0
  90. package/web/dist/assets/cs-C9cckHFh.js +1 -0
  91. package/web/dist/assets/da-BpNIZAZo.js +1 -0
  92. package/web/dist/assets/de-C1DX_kDk.js +1 -0
  93. package/web/dist/assets/es-bymdOEnB.js +1 -0
  94. package/web/dist/assets/fi-p1DAJXf3.js +1 -0
  95. package/web/dist/assets/fr-w1qH9bbD.js +1 -0
  96. package/web/dist/assets/hi-DnZJakpY.js +1 -0
  97. package/web/dist/assets/{hls-3VKVEQE3-_BiJh76x.js → hls-3VKVEQE3-DURNoQ5W.js} +1 -1
  98. package/web/dist/assets/hu-N7uSyLAk.js +1 -0
  99. package/web/dist/assets/id-CX3MVU3E.js +1 -0
  100. package/web/dist/assets/index-BXJlt2r6.js +3 -0
  101. package/web/dist/assets/index-Brm9OAsr.css +1 -0
  102. package/web/dist/assets/it-CQ0H28FI.js +1 -0
  103. package/web/dist/assets/{mpegts-CV0glck7.js → mpegts-BdyqUrVC.js} +1 -1
  104. package/web/dist/assets/{mpegts-LO6RVLD6-iuTMg-O6.js → mpegts-LO6RVLD6-yGogIzG9.js} +1 -1
  105. package/web/dist/assets/nl-DJqCLHMq.js +1 -0
  106. package/web/dist/assets/ru-Rk2yagke.js +1 -0
  107. package/web/dist/assets/sv-1r9eOl4-.js +1 -0
  108. package/web/dist/assets/uk-CrRsLNHV.js +1 -0
  109. package/web/dist/assets/vi-B5kxrjP7.js +1 -0
  110. package/web/dist/assets/zh-BB_S8QpG.js +1 -0
  111. package/web/dist/index.html +132 -131
  112. package/web/dist/sw.js +23 -6
  113. package/backtoschool/dist/assets/index-Cjai7LgT.js +0 -93
  114. package/web/dist/assets/index-BgLxkXKe.js +0 -3
  115. package/web/dist/assets/index-D34dTY18.css +0 -1
@@ -0,0 +1,201 @@
1
+ declare const _default: {
2
+ "Interface language": string;
3
+ Language: string;
4
+ "Translation language": string;
5
+ "Original (auto-detect)": string;
6
+ Play: string;
7
+ Pause: string;
8
+ Stop: string;
9
+ Next: string;
10
+ Previous: string;
11
+ Select: string;
12
+ "Next/Prev": string;
13
+ Quit: string;
14
+ "Now Playing": string;
15
+ "Spectrum Analyser": string;
16
+ Playlist: string;
17
+ Files: string;
18
+ "Open files": string;
19
+ "Open folder": string;
20
+ "Add to library": string;
21
+ "Replace playlist": string;
22
+ Filter: string;
23
+ Search: string;
24
+ "Nothing loaded.": string;
25
+ "Empty.": string;
26
+ "Loading\u2026": string;
27
+ "Connecting\u2026": string;
28
+ Connected: string;
29
+ "Not connected": string;
30
+ "No source": string;
31
+ Playing: string;
32
+ Stopped: string;
33
+ Volume: string;
34
+ Seek: string;
35
+ "Full screen": string;
36
+ Download: string;
37
+ Share: string;
38
+ Copy: string;
39
+ "Copy link": string;
40
+ Copied: string;
41
+ Save: string;
42
+ Cancel: string;
43
+ Close: string;
44
+ Remove: string;
45
+ Delete: string;
46
+ Edit: string;
47
+ Add: string;
48
+ Send: string;
49
+ Retry: string;
50
+ Back: string;
51
+ "Next page": string;
52
+ "Previous page": string;
53
+ "Show more": string;
54
+ Panels: string;
55
+ "Reset layout": string;
56
+ Show: string;
57
+ Hide: string;
58
+ Collapse: string;
59
+ Expand: string;
60
+ "Move up": string;
61
+ "Move down": string;
62
+ Install: string;
63
+ "TV mode": string;
64
+ On: string;
65
+ Off: string;
66
+ Account: string;
67
+ "Sign in": string;
68
+ "Sign out": string;
69
+ "Create account": string;
70
+ Email: string;
71
+ Password: string;
72
+ "Forgot password?": string;
73
+ "Welcome back": string;
74
+ Profile: string;
75
+ Handle: string;
76
+ "Your servers": string;
77
+ Server: string;
78
+ Connect: string;
79
+ Disconnect: string;
80
+ Directory: string;
81
+ Favourites: string;
82
+ Follow: string;
83
+ Unfollow: string;
84
+ Notifications: string;
85
+ "Phone number": string;
86
+ "Save number": string;
87
+ Transcript: string;
88
+ Captions: string;
89
+ "Translate audio": string;
90
+ "Audio language": string;
91
+ "Audio options": string;
92
+ "Keep background sound": string;
93
+ "Background level": string;
94
+ "Speaker voices": string;
95
+ "Any voice": string;
96
+ "Male voice": string;
97
+ "Female voice": string;
98
+ "Original audio.": string;
99
+ "Buy translated audio": string;
100
+ "Audio credit": string;
101
+ "Buy pass": string;
102
+ Pass: string;
103
+ "Pay with": string;
104
+ "Check payment": string;
105
+ "Open checkout": string;
106
+ "Free sessions": string;
107
+ "Usage rates and expiry": string;
108
+ Catalogs: string;
109
+ "Add catalog": string;
110
+ "Catalog name": string;
111
+ Link: string;
112
+ "Play link": string;
113
+ "Go live": string;
114
+ Publish: string;
115
+ Listen: string;
116
+ "Live now": string;
117
+ Upcoming: string;
118
+ Parties: string;
119
+ "Join party": string;
120
+ "Invite code": string;
121
+ Invite: string;
122
+ Chat: string;
123
+ "Chat message": string;
124
+ People: string;
125
+ Speaker: string;
126
+ Speakers: string;
127
+ Listener: string;
128
+ Moderator: string;
129
+ "Raise hand": string;
130
+ "Hand raises": string;
131
+ Questions: string;
132
+ Resources: string;
133
+ Replay: string;
134
+ Schedule: string;
135
+ Event: string;
136
+ Host: string;
137
+ About: string;
138
+ Stage: string;
139
+ Title: string;
140
+ Description: string;
141
+ Topic: string;
142
+ Public: string;
143
+ "Anyone with the link": string;
144
+ "Invited people": string;
145
+ "Who can join": string;
146
+ "Date and time": string;
147
+ "Expected length": string;
148
+ Repeat: string;
149
+ "Does not repeat": string;
150
+ "Every day": string;
151
+ "Every week": string;
152
+ Homepage: string;
153
+ "Host name": string;
154
+ "Profile photo URL": string;
155
+ "Broadcast link": string;
156
+ "Edit event": string;
157
+ "Save changes": string;
158
+ "Create live": string;
159
+ "Schedule class": string;
160
+ "Start class": string;
161
+ "End event": string;
162
+ "End session": string;
163
+ "Session ended": string;
164
+ "Event ended": string;
165
+ Cancelled: string;
166
+ "Replay available": string;
167
+ Join: string;
168
+ "Create invite": string;
169
+ "Invite as": string;
170
+ "Watch now": string;
171
+ "Start a room": string;
172
+ "Recent replays": string;
173
+ "Your account": string;
174
+ "Write with AI": string;
175
+ "Suggested title": string;
176
+ "Suggested description": string;
177
+ "Suggested topic": string;
178
+ "Use these details": string;
179
+ "Learn something live.": string;
180
+ "Screen share": string;
181
+ "Upload and broadcast": string;
182
+ Help: string;
183
+ "Reload Player": string;
184
+ "Copy Bundled CLI Path": string;
185
+ "Developer tools": string;
186
+ Undo: string;
187
+ Redo: string;
188
+ Cut: string;
189
+ Paste: string;
190
+ "Select all": string;
191
+ Status: string;
192
+ "Activity log": string;
193
+ Admin: string;
194
+ "Playback controls": string;
195
+ "Tracks and folders": string;
196
+ "Original-language captions.": string;
197
+ "Skip to playback controls": string;
198
+ "Skip to playlist": string;
199
+ "Skip to transcript and translated audio": string;
200
+ };
201
+ export default _default;
@@ -0,0 +1,200 @@
1
+ export default {
2
+ "Interface language": "界面语言",
3
+ "Language": "语言",
4
+ "Translation language": "翻译语言",
5
+ "Original (auto-detect)": "原文(自动检测)",
6
+ "Play": "播放",
7
+ "Pause": "暂停",
8
+ "Stop": "停止",
9
+ "Next": "下一个",
10
+ "Previous": "上一个",
11
+ "Select": "选择",
12
+ "Next/Prev": "下一个/上一个",
13
+ "Quit": "退出",
14
+ "Now Playing": "正在播放",
15
+ "Spectrum Analyser": "频谱分析仪",
16
+ "Playlist": "播放列表",
17
+ "Files": "文件",
18
+ "Open files": "打开文件",
19
+ "Open folder": "打开文件夹",
20
+ "Add to library": "添加到媒体库",
21
+ "Replace playlist": "替换播放列表",
22
+ "Filter": "筛选",
23
+ "Search": "搜索",
24
+ "Nothing loaded.": "尚未加载内容。",
25
+ "Empty.": "空。",
26
+ "Loading…": "正在加载…",
27
+ "Connecting…": "正在连接…",
28
+ "Connected": "已连接",
29
+ "Not connected": "未连接",
30
+ "No source": "无来源",
31
+ "Playing": "播放中",
32
+ "Stopped": "已停止",
33
+ "Volume": "音量",
34
+ "Seek": "播放位置",
35
+ "Full screen": "全屏",
36
+ "Download": "下载",
37
+ "Share": "分享",
38
+ "Copy": "复制",
39
+ "Copy link": "复制链接",
40
+ "Copied": "已复制",
41
+ "Save": "保存",
42
+ "Cancel": "取消",
43
+ "Close": "关闭",
44
+ "Remove": "移除",
45
+ "Delete": "删除",
46
+ "Edit": "编辑",
47
+ "Add": "添加",
48
+ "Send": "发送",
49
+ "Retry": "重试",
50
+ "Back": "返回",
51
+ "Next page": "下一页",
52
+ "Previous page": "上一页",
53
+ "Show more": "显示更多",
54
+ "Panels": "面板",
55
+ "Reset layout": "重置布局",
56
+ "Show": "显示",
57
+ "Hide": "隐藏",
58
+ "Collapse": "收起",
59
+ "Expand": "展开",
60
+ "Move up": "上移",
61
+ "Move down": "下移",
62
+ "Install": "安装",
63
+ "TV mode": "电视模式",
64
+ "On": "开启",
65
+ "Off": "关闭",
66
+ "Account": "账户",
67
+ "Sign in": "登录",
68
+ "Sign out": "退出登录",
69
+ "Create account": "创建账户",
70
+ "Email": "电子邮箱",
71
+ "Password": "密码",
72
+ "Forgot password?": "忘记密码?",
73
+ "Welcome back": "欢迎回来",
74
+ "Profile": "个人资料",
75
+ "Handle": "用户名",
76
+ "Your servers": "你的服务器",
77
+ "Server": "服务器",
78
+ "Connect": "连接",
79
+ "Disconnect": "断开连接",
80
+ "Directory": "目录",
81
+ "Favourites": "收藏",
82
+ "Follow": "关注",
83
+ "Unfollow": "取消关注",
84
+ "Notifications": "通知",
85
+ "Phone number": "电话号码",
86
+ "Save number": "保存号码",
87
+ "Transcript": "文字稿",
88
+ "Captions": "字幕",
89
+ "Translate audio": "翻译音频",
90
+ "Audio language": "音频语言",
91
+ "Audio options": "音频选项",
92
+ "Keep background sound": "保留背景声音",
93
+ "Background level": "背景音量",
94
+ "Speaker voices": "说话者声音",
95
+ "Any voice": "任意声音",
96
+ "Male voice": "男声",
97
+ "Female voice": "女声",
98
+ "Original audio.": "原始音频。",
99
+ "Buy translated audio": "购买翻译音频",
100
+ "Audio credit": "音频余额",
101
+ "Buy pass": "购买通行证",
102
+ "Pass": "通行证",
103
+ "Pay with": "支付方式",
104
+ "Check payment": "检查付款",
105
+ "Open checkout": "前往付款",
106
+ "Free sessions": "免费会话",
107
+ "Usage rates and expiry": "使用费率与有效期",
108
+ "Catalogs": "内容目录",
109
+ "Add catalog": "添加目录",
110
+ "Catalog name": "目录名称",
111
+ "Link": "链接",
112
+ "Play link": "播放链接",
113
+ "Go live": "开始直播",
114
+ "Publish": "发布",
115
+ "Listen": "收听",
116
+ "Live now": "正在直播",
117
+ "Upcoming": "即将开始",
118
+ "Parties": "一起看",
119
+ "Join party": "加入一起看",
120
+ "Invite code": "邀请码",
121
+ "Invite": "邀请",
122
+ "Chat": "聊天",
123
+ "Chat message": "聊天消息",
124
+ "People": "参与者",
125
+ "Speaker": "发言者",
126
+ "Speakers": "发言者",
127
+ "Listener": "听众",
128
+ "Moderator": "主持人",
129
+ "Raise hand": "举手",
130
+ "Hand raises": "举手列表",
131
+ "Questions": "问题",
132
+ "Resources": "资料",
133
+ "Replay": "回放",
134
+ "Schedule": "日程",
135
+ "Event": "活动",
136
+ "Host": "主办人",
137
+ "About": "关于",
138
+ "Stage": "舞台",
139
+ "Title": "标题",
140
+ "Description": "描述",
141
+ "Topic": "主题",
142
+ "Public": "公开",
143
+ "Anyone with the link": "拥有链接的任何人",
144
+ "Invited people": "受邀者",
145
+ "Who can join": "谁可以加入",
146
+ "Date and time": "日期与时间",
147
+ "Expected length": "预计时长",
148
+ "Repeat": "重复",
149
+ "Does not repeat": "不重复",
150
+ "Every day": "每天",
151
+ "Every week": "每周",
152
+ "Homepage": "网站",
153
+ "Host name": "主办人姓名",
154
+ "Profile photo URL": "头像网址",
155
+ "Broadcast link": "直播链接",
156
+ "Edit event": "编辑活动",
157
+ "Save changes": "保存更改",
158
+ "Create live": "创建直播",
159
+ "Schedule class": "安排课程",
160
+ "Start class": "开始课程",
161
+ "End event": "结束活动",
162
+ "End session": "结束本次会话",
163
+ "Session ended": "会话已结束",
164
+ "Event ended": "活动已结束",
165
+ "Cancelled": "已取消",
166
+ "Replay available": "可观看回放",
167
+ "Join": "加入",
168
+ "Create invite": "创建邀请",
169
+ "Invite as": "邀请身份",
170
+ "Watch now": "立即观看",
171
+ "Start a room": "创建房间",
172
+ "Recent replays": "近期回放",
173
+ "Your account": "你的账户",
174
+ "Write with AI": "用 AI 撰写",
175
+ "Suggested title": "建议标题",
176
+ "Suggested description": "建议描述",
177
+ "Suggested topic": "建议主题",
178
+ "Use these details": "使用这些信息",
179
+ "Learn something live.": "实时学习新知识。",
180
+ "Screen share": "共享屏幕",
181
+ "Upload and broadcast": "上传并直播",
182
+ "Help": "帮助",
183
+ "Reload Player": "重新加载播放器",
184
+ "Copy Bundled CLI Path": "复制内置命令行工具路径",
185
+ "Developer tools": "开发者工具",
186
+ "Undo": "撤销",
187
+ "Redo": "重做",
188
+ "Cut": "剪切",
189
+ "Paste": "粘贴",
190
+ "Select all": "全选",
191
+ "Status": "状态",
192
+ "Activity log": "活动日志",
193
+ "Admin": "管理",
194
+ "Playback controls": "播放控制",
195
+ "Tracks and folders": "曲目与文件夹",
196
+ "Original-language captions.": "原语言字幕。",
197
+ "Skip to playback controls": "跳转到播放控制",
198
+ "Skip to playlist": "跳转到播放列表",
199
+ "Skip to transcript and translated audio": "跳转到文字稿和翻译音频"
200
+ };
package/dist/main.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { t as uiMessage, i18n, terminalUiLanguage, uiLanguage } from "./i18n.js";
1
2
  /**
2
3
  * nixamp — it really whips the terminal's ass.
3
4
  *
@@ -119,6 +120,7 @@ Keys in the player:
119
120
  d detach: hand the music to a daemon and get the terminal back
120
121
  q quit
121
122
 
123
+ --ui-language CODE interface language (default: system language; fallback: English)
122
124
  -v, --version print the version
123
125
  -h, --help print this. \`nixamp help <command>\` says more about one
124
126
  `;
@@ -482,7 +484,19 @@ async function runDaemon(argv) {
482
484
  * because the flag is false in a module that was imported rather than run.
483
485
  */
484
486
  export async function main() {
485
- const [first, ...rest] = process.argv.slice(2);
487
+ const args = process.argv.slice(2);
488
+ const languageAt = args.findIndex(arg => arg === "--ui-language" || arg.startsWith("--ui-language="));
489
+ let language = terminalUiLanguage(process.env);
490
+ if (languageAt >= 0) {
491
+ const flag = args[languageAt];
492
+ const value = flag.includes("=") ? flag.slice(flag.indexOf("=") + 1) : args[languageAt + 1];
493
+ if (!value || value.startsWith("-"))
494
+ throw new Error("nixamp: --ui-language needs a language code, e.g. de");
495
+ language = uiLanguage(value);
496
+ args.splice(languageAt, flag.includes("=") ? 1 : 2);
497
+ }
498
+ await i18n.setLanguage(language);
499
+ const [first, ...rest] = args;
486
500
  // Asked for however anybody asks for it. `nixamp help serve` and
487
501
  // `nixamp serve --help` are the same question, so they get the same answer.
488
502
  if (wantsHelp(first, rest)) {
@@ -836,15 +850,15 @@ export function view({ ui, theme, height }, state) {
836
850
  const progress = duration > 0 ? Math.min(1, state.position / duration) : 0;
837
851
  ui.row({ size: 1 }, (header) => {
838
852
  header.text(" ⣿ NIXAMP", { fg: theme.title, bold: true, size: 11 });
839
- header.text(state.playing ? "▶ PLAYING" : "■ STOPPED", {
853
+ header.text(state.playing ? uiMessage("▶ PLAYING") : uiMessage("■ STOPPED"), {
840
854
  fg: state.playing ? theme.success : theme.muted,
841
855
  size: 12,
842
856
  });
843
857
  header.text(`${state.tracks.length} tracks ${state.root} `, { fg: theme.muted, align: "right" });
844
858
  });
845
- ui.panel({ title: "Now Playing", size: 6 }, (p) => {
859
+ ui.panel({ title: uiMessage("Now Playing"), size: 6 }, (p) => {
846
860
  if (!track) {
847
- p.label("Nothing loaded.");
861
+ p.label(uiMessage("Nothing loaded."));
848
862
  return;
849
863
  }
850
864
  p.text(displayName(track), { fg: theme.accent, bold: true, size: 1 });
@@ -858,7 +872,7 @@ export function view({ ui, theme, height }, state) {
858
872
  });
859
873
  });
860
874
  ui.row({ size: height - 10, gap: 1 }, (row) => {
861
- row.panel({ title: "Spectrum Analyser", width: "1.3fr" }, (p) => {
875
+ row.panel({ title: uiMessage("Spectrum Analyser"), width: "1.3fr" }, (p) => {
862
876
  // Braille gives four vertical pixels per cell, so the bars move smoothly
863
877
  // rather than stepping through eight block glyphs.
864
878
  p.canvas((canvas) => {
@@ -870,9 +884,9 @@ export function view({ ui, theme, height }, state) {
870
884
  `R${"▮".repeat(Math.round(state.levels[1] * 6)).padEnd(6, "·")}`, { fg: theme.accent, align: "right" });
871
885
  });
872
886
  });
873
- row.panel({ title: `Playlist (${state.tracks.length})`, width: "1fr" }, (p) => {
887
+ row.panel({ title: `${uiMessage("Playlist")} (${i18n.number(state.tracks.length)})`, width: "1fr" }, (p) => {
874
888
  if (state.tracks.length === 0) {
875
- p.label("Empty.");
889
+ p.label(uiMessage("Empty."));
876
890
  return;
877
891
  }
878
892
  p.table({
@@ -903,11 +917,11 @@ export function view({ ui, theme, height }, state) {
903
917
  ui.text(state.note, { fg: theme.warning, size: 1 });
904
918
  ui.statusBar({
905
919
  items: [
906
- { key: "Space", label: state.playing ? "Stop" : "Play", active: state.playing },
907
- { key: "↑↓", label: "Select" },
908
- { key: "n/p", label: "Next/Prev" },
909
- { key: "Enter", label: "Play" },
910
- { key: "q", label: "Quit" },
920
+ { key: "Space", label: state.playing ? uiMessage("Stop") : uiMessage("Play"), active: state.playing },
921
+ { key: "↑↓", label: uiMessage("Select") },
922
+ { key: "n/p", label: uiMessage("Next/Prev") },
923
+ { key: "Enter", label: uiMessage("Play") },
924
+ { key: "q", label: uiMessage("Quit") },
911
925
  ],
912
926
  });
913
927
  }
@@ -0,0 +1,4 @@
1
+ import type { Message } from './i18n.ts';
2
+ /** Existing copy can use a concise shared label in translated interfaces.
3
+ * English remains verbatim. Never use these aliases for user-authored content. */
4
+ export declare const aliases: Record<string, Message>;
@@ -0,0 +1,41 @@
1
+ /** Existing copy can use a concise shared label in translated interfaces.
2
+ * English remains verbatim. Never use these aliases for user-authored content. */
3
+ export const aliases = {
4
+ '■ STOPPED': 'Stopped', '▶ PLAYING': 'Playing', 'LOADING': 'Loading…',
5
+ 'no source': 'No source', 'not connected': 'Not connected', 'Now playing': 'Now Playing',
6
+ '● GO LIVE': 'Go live', '● Go live': 'Go live', '⤓ Download': 'Download',
7
+ 'A man\'s voice': 'Male voice', 'A woman\'s voice': 'Female voice',
8
+ 'Catalogs on this server': 'Catalogs', 'Catalog folders': 'Catalogs',
9
+ 'Parties on this server': 'Parties', 'Servers streaming now': 'Directory',
10
+ 'Playlist (0)': 'Playlist', 'Playlist folders': 'Playlist', 'Playlist pages': 'Playlist',
11
+ 'Filter these files': 'Filter', 'Filter these entries': 'Filter',
12
+ 'Filter the entries': 'Filter', 'Filter the playlist': 'Filter',
13
+ 'Create a free account': 'Create account', 'Create one': 'Create account',
14
+ 'Create your account': 'Create account', 'New here? Create an account': 'Create account',
15
+ 'Already have an account? Sign in': 'Sign in', 'Your NixAmp account': 'Your account',
16
+ 'Your public handle': 'Handle', 'handle': 'Handle', 'password': 'Password',
17
+ 'Phone number for texts': 'Phone number', 'Back to the player': 'Back',
18
+ 'Share what is playing': 'Share', 'Share this stream': 'Share',
19
+ 'Link to this stream': 'Link', 'Copy this stream\'s URL': 'Copy link',
20
+ 'A link to play': 'Link', 'A server\'s link': 'Server', 'Close translated audio purchase': 'Close',
21
+ 'Open secure checkout ↗ (new tab)': 'Open checkout', 'Checking…': 'Loading…',
22
+ 'Browse the directory': 'Directory', 'See what is live': 'Live now',
23
+ 'Join live': 'Join', 'Raise Hand': 'Raise hand', 'Hand Raises': 'Hand raises',
24
+ 'Hide this': 'Hide', 'Log': 'Activity log', 'Status:': 'Status',
25
+ 'Nixamp player': 'Playback controls', 'Nixamp audio and video player': 'Playback controls',
26
+ 'What is being said': 'Transcript', 'The room\'s chat': 'Chat', 'Trollbox': 'Chat',
27
+ 'A line for the trollbox': 'Chat message', 'Say something to the room…': 'Chat message',
28
+ 'Send it': 'Send', 'Something to add': 'Chat message', 'What to call it': 'Catalog name',
29
+ 'call it something': 'Catalog name', 'An m3u catalog to add': 'Catalogs',
30
+ 'On this device': 'Play', 'Play on this device': 'Play', 'What this is': 'About',
31
+ 'Looking for servers…': 'Loading…', 'Finding today’s conversations…': 'Loading…',
32
+ 'Coming up': 'Upcoming', 'Listen after class': 'Replay', 'Schedule live': 'Schedule class',
33
+ 'Schedule a class': 'Schedule class', 'Plan a conversation': 'Schedule class',
34
+ 'Your classroom': 'Event', 'Join in': 'Join', 'Open a room →': 'Start a room',
35
+ 'Chat message': 'Chat message', 'Add to the conversation': 'Chat message',
36
+ 'Create live': 'Create live', 'Host stage': 'Stage', 'Your host': 'Host',
37
+ 'Class host': 'Host', 'Hand raised ✓': 'Raise hand', 'Copied ✓': 'Copied',
38
+ 'Screen share with Pairux ↗': 'Screen share', 'Upload & broadcast in Nixamp ↗': 'Upload and broadcast',
39
+ 'Open Music Folder…': 'Open folder', 'Choose a music folder': 'Open folder',
40
+ 'Main navigation': 'Panels', 'Skip to a section': 'Panels',
41
+ };
@@ -0,0 +1,62 @@
1
+ /** The UI and audio-translation menus share the same supported targets. */
2
+ export declare const UI_LANGUAGES: readonly [{
3
+ readonly code: 'en';
4
+ readonly label: 'English';
5
+ }, {
6
+ readonly code: 'de';
7
+ readonly label: 'Deutsch';
8
+ }, {
9
+ readonly code: 'sv';
10
+ readonly label: 'Svenska';
11
+ }, {
12
+ readonly code: 'es';
13
+ readonly label: 'Español';
14
+ }, {
15
+ readonly code: 'fr';
16
+ readonly label: 'Français';
17
+ }, {
18
+ readonly code: 'it';
19
+ readonly label: 'Italiano';
20
+ }, {
21
+ readonly code: 'nl';
22
+ readonly label: 'Nederlands';
23
+ }, {
24
+ readonly code: 'da';
25
+ readonly label: 'Dansk';
26
+ }, {
27
+ readonly code: 'fi';
28
+ readonly label: 'Suomi';
29
+ }, {
30
+ readonly code: 'ru';
31
+ readonly label: 'Русский';
32
+ }, {
33
+ readonly code: 'uk';
34
+ readonly label: 'Українська';
35
+ }, {
36
+ readonly code: 'cs';
37
+ readonly label: 'Čeština';
38
+ }, {
39
+ readonly code: 'hu';
40
+ readonly label: 'Magyar';
41
+ }, {
42
+ readonly code: 'zh';
43
+ readonly label: '中文';
44
+ }, {
45
+ readonly code: 'ar';
46
+ readonly label: 'العربية';
47
+ }, {
48
+ readonly code: 'hi';
49
+ readonly label: 'हिन्दी';
50
+ }, {
51
+ readonly code: 'vi';
52
+ readonly label: 'Tiếng Việt';
53
+ }, {
54
+ readonly code: 'id';
55
+ readonly label: 'Bahasa Indonesia';
56
+ }];
57
+ export type UiLanguage = typeof UI_LANGUAGES[number]['code'];
58
+ export declare const UI_LANGUAGE_KEY = "nixamp.ui.language";
59
+ export declare function uiLanguage(value: unknown): UiLanguage;
60
+ /** A saved choice wins; otherwise use the first supported system preference. */
61
+ export declare function preferredUiLanguage(saved: unknown, system?: readonly unknown[]): UiLanguage;
62
+ export declare function terminalUiLanguage(env: Record<string, string | undefined>): UiLanguage;
@@ -0,0 +1,32 @@
1
+ /** The UI and audio-translation menus share the same supported targets. */
2
+ export const UI_LANGUAGES = [
3
+ { code: 'en', label: 'English' }, { code: 'de', label: 'Deutsch' },
4
+ { code: 'sv', label: 'Svenska' }, { code: 'es', label: 'Español' },
5
+ { code: 'fr', label: 'Français' }, { code: 'it', label: 'Italiano' },
6
+ { code: 'nl', label: 'Nederlands' }, { code: 'da', label: 'Dansk' },
7
+ { code: 'fi', label: 'Suomi' }, { code: 'ru', label: 'Русский' },
8
+ { code: 'uk', label: 'Українська' }, { code: 'cs', label: 'Čeština' },
9
+ { code: 'hu', label: 'Magyar' }, { code: 'zh', label: '中文' },
10
+ { code: 'ar', label: 'العربية' }, { code: 'hi', label: 'हिन्दी' },
11
+ { code: 'vi', label: 'Tiếng Việt' }, { code: 'id', label: 'Bahasa Indonesia' },
12
+ ];
13
+ export const UI_LANGUAGE_KEY = 'nixamp.ui.language';
14
+ export function uiLanguage(value) {
15
+ const code = typeof value === 'string' ? value.trim().toLowerCase().split(/[-_.@]/)[0] : '';
16
+ return UI_LANGUAGES.find(language => language.code === code)?.code ?? 'en';
17
+ }
18
+ /** A saved choice wins; otherwise use the first supported system preference. */
19
+ export function preferredUiLanguage(saved, system = []) {
20
+ const match = (value) => {
21
+ const code = typeof value === 'string' ? value.trim().toLowerCase().split(/[-_.@]/)[0] : '';
22
+ return UI_LANGUAGES.find(language => language.code === code)?.code;
23
+ };
24
+ return match(saved) ?? system.map(match).find(Boolean) ?? 'en';
25
+ }
26
+ export function terminalUiLanguage(env) {
27
+ if (env['NIXAMP_UI_LANGUAGE'])
28
+ return uiLanguage(env['NIXAMP_UI_LANGUAGE']);
29
+ if (env['LC_ALL'])
30
+ return preferredUiLanguage(null, [env['LC_ALL']]);
31
+ return preferredUiLanguage(null, env['LANGUAGE']?.split(':') ?? [env['LC_MESSAGES'] || env['LANG']]);
32
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nixamp",
3
- "version": "0.27.3",
3
+ "version": "0.28.0",
4
4
  "description": "It really whips the terminal's ass. A Winamp-shaped audio player for your terminal.",
5
5
  "license": "MIT",
6
6
  "type": "module",