feat: added german translation and in the process a new translation system, close #1221, credit @Totto16

This commit is contained in:
DIYgod 2022-08-15 21:38:52 +01:00
parent b429b9a5b7
commit ef273ec42a
No known key found for this signature in database
GPG Key ID: D159328F47A80DCA
8 changed files with 285 additions and 160 deletions

View File

@ -88,6 +88,7 @@ function initPlayers() {
logo: 'https://i.loli.net/2019/06/06/5cf8c5d94521136430.png',
volume: 0.2,
mutex: true,
lang: 'zh-cn',
video: {
url: 'https://api.dogecloud.com/player/get.mp4?vcode=5ac682e6f8231991&userId=17&ext=.mp4',
pic: 'https://i.loli.net/2019/06/06/5cf8c5d9c57b510947.png',
@ -140,7 +141,7 @@ function initPlayers() {
const eventsEle = document.getElementById('events');
for (let i = 0; i < events.length; i++) {
dp2.on(events[i], (info) => {
eventsEle.innerHTML += '<p>Event: ' + events[i] + '</p>';
eventsEle.innerHTML += `<p>Event: ${events[i]} ${info?`Data: <span>${JSON.stringify(info)}</span>`:''}</p>`;
eventsEle.scrollTop = eventsEle.scrollHeight;
});
}

View File

@ -76,7 +76,7 @@ class Comment {
// text can't be empty
if (!this.player.template.commentInput.value.replace(/^\s+|\s+$/g, '')) {
this.player.notice(this.player.tran('Please input danmaku content!'));
this.player.notice(this.player.tran('please-input-danmaku'));
return;
}

View File

@ -366,12 +366,12 @@ class Controller {
initSubtitleButton() {
if (this.player.options.subtitle) {
this.player.events.on('subtitle_show', () => {
this.player.template.subtitleButton.dataset.balloon = this.player.tran('Hide subtitle');
this.player.template.subtitleButton.dataset.balloon = this.player.tran('hide-subs');
this.player.template.subtitleButtonInner.style.opacity = '';
this.player.user.set('subtitle', 1);
});
this.player.events.on('subtitle_hide', () => {
this.player.template.subtitleButton.dataset.balloon = this.player.tran('Show subtitle');
this.player.template.subtitleButton.dataset.balloon = this.player.tran('show-subs');
this.player.template.subtitleButtonInner.style.opacity = '0.4';
this.player.user.set('subtitle', 0);
});

View File

@ -70,7 +70,7 @@ class Danmaku {
}
},
error: (msg) => {
this.options.error(msg || this.options.tran('Danmaku load failed'));
this.options.error(msg || this.options.tran('danmaku-failed'));
results[i] = [];
++readCount;
@ -97,7 +97,7 @@ class Danmaku {
data: danmakuData,
success: callback,
error: (msg) => {
this.options.error(msg || this.options.tran('Danmaku send failed'));
this.options.error(msg || this.options.tran('danmaku-failed'));
},
});

View File

@ -9,139 +9,263 @@ Use this as shown below..... */
function i18n(lang) {
this.lang = lang;
this.tran = (text) => {
if (tranTxt[this.lang] && tranTxt[this.lang][text]) {
return tranTxt[this.lang][text];
// in case someone says en-us, and en is present!
this.fallbackLang = this.lang.includes('-') ? this.lang.split('-')[0] : this.lang;
this.tran = (key) => {
key = key.toLowerCase();
if (tranTxt[this.lang] && tranTxt[this.lang][key]) {
return tranTxt[this.lang][key];
} else if (tranTxt[this.fallbackLang] && tranTxt[this.fallbackLang][key]) {
return tranTxt[this.fallbackLang][key];
} else {
return text;
return standard[key];
}
};
}
// abstract model for recognizing if valid translations are present
// const model = {
// 'danmaku-loading': [],
// top: [],
// bottom: [],
// rolling: [],
// 'input-danmaku-enter': [],
// 'about-author': [],
// 'dplayer-feedback': [],
// 'about-dplayer': [],
// loop: [],
// speed: [],
// 'opacity-danmaku': [],
// normal: [],
// 'please-input-danmaku': [],
// 'set-danmaku-color': [],
// 'set-danmaku-type': [],
// 'show-danmaku': [],
// 'video-failed': [],
// 'danmaku-failed': [],
// 'danmaku-send-failed': [],
// 'switching-quality': [{ symbol: '%q', name: 'Quality', example: '720p' }],
// 'switched-quality': [{ symbol: '%q', name: 'Quality', example: '720p' }],
// ff: [{ symbol: '%s', name: 'Seconds', example: '5' }],
// rew: [{ symbol: '%s', name: 'Seconds', example: '5' }],
// 'unlimited-danmaku': [],
// 'send-danmaku': [],
// setting: [],
// fullscreen: [],
// 'web-fullscreen': [],
// send: [],
// screenshot: [],
// airplay: [],
// chromecast: [],
// 'show-subs': [],
// 'hide-subs': [],
// volume: [],
// live: [],
// 'video-info': [],
// };
// Standard english translations
const standard = {
'danmaku-loading': 'Danmaku is loading',
top: 'Top',
bottom: 'Bottom',
rolling: 'Rolling',
'input-danmaku-enter': 'Input danmaku, hit Enter',
'about-author': 'About author',
'dplayer-feedback': 'DPlayer feedback',
'about-dplayer': 'About DPlayer',
loop: 'Loop',
speed: 'Speed',
'opacity-danmaku': 'Opacity for danmaku',
normal: 'Normal',
'please-input-danmaku': 'Please input danmaku content!',
'set-danmaku-color': 'Set danmaku color',
'set-danmaku-type': 'Set danmaku type',
'show-danmaku': 'Show danmaku',
'video-failed': 'Video load failed',
'danmaku-failed': 'Danmaku load failed',
'danmaku-send-failed': 'Danmaku send failed',
'switching-quality': 'Switching to %q quality',
'switched-quality': 'Switched to %q quality',
ff: 'FF %s s',
rew: 'REW %s s',
'unlimited-danmaku': 'Unlimited danmaku',
'send-danmaku': 'Send danmaku',
setting: 'Setting',
fullscreen: 'Full screen',
'web-fullscreen': 'Web full screen',
send: 'Send',
screenshot: 'Screenshot',
airplay: 'AirPlay',
chromecast: 'ChromeCast',
'show-subs': 'Show subtitle',
'hide-subs': 'Hide subtitle',
volume: 'Volume',
live: 'Live',
'video-info': 'Video info',
};
// add translation text here
const tranTxt = {
en: standard,
'zh-cn': {
'Danmaku is loading': '弹幕加载中',
Top: '顶部',
Bottom: '底部',
Rolling: '滚动',
'Input danmaku, hit Enter': '输入弹幕,回车发送',
'About author': '关于作者',
'DPlayer feedback': '播放器意见反馈',
'About DPlayer': '关于 DPlayer 播放器',
Loop: '洗脑循环',
Speed: '速度',
'Opacity for danmaku': '弹幕透明度',
Normal: '正常',
'Please input danmaku content!': '要输入弹幕内容啊喂!',
'Set danmaku color': '设置弹幕颜色',
'Set danmaku type': '设置弹幕类型',
'Show danmaku': '显示弹幕',
'Video load failed': '视频加载失败',
'Danmaku load failed': '弹幕加载失败',
'Danmaku send failed': '弹幕发送失败',
'Switching to': '正在切换至',
'Switched to': '已经切换至',
quality: '画质',
FF: '快进',
REW: '快退',
'Unlimited danmaku': '海量弹幕',
'Send danmaku': '发送弹幕',
Setting: '设置',
'Full screen': '全屏',
'Web full screen': '页面全屏',
Send: '发送',
Screenshot: '截图',
AirPlay: '无线投屏',
ChromeCast: 'ChromeCast',
s: '秒',
'Show subtitle': '显示字幕',
'Hide subtitle': '隐藏字幕',
Volume: '音量',
Live: '直播',
'Video info': '视频统计信息',
'danmaku-loading': '弹幕加载中',
top: '顶部',
bottom: '底部',
rolling: '滚动',
'input-danmaku-enter': '输入弹幕,回车发送',
'about-author': '关于作者',
'dplayer-feedback': '播放器意见反馈',
'about-dplayer': '关于 DPlayer 播放器',
loop: '洗脑循环',
speed: '速度',
'opacity-danmaku': '弹幕透明度',
normal: '正常',
'please-input-danmaku': '要输入弹幕内容啊喂!',
'set-danmaku-color': '设置弹幕颜色',
'set-danmaku-type': '设置弹幕类型',
'show-danmaku': '显示弹幕',
'video-failed': '视频加载失败',
'danmaku-failed': '弹幕加载失败',
'danmaku-send-failed': '弹幕发送失败',
'switching-quality': '正在切换至 %q 画质',
'switched-quality': '已经切换至 %q 画质',
ff: '快进 %s 秒',
rew: '快退 %s 秒',
'unlimited-danmaku': '海量弹幕',
'send-danmaku': '发送弹幕',
setting: '设置',
fullscreen: '全屏',
'web-fullscreen': '页面全屏',
send: '发送',
screenshot: '截图',
airplay: '无线投屏',
chromecast: 'ChromeCast',
'show-subs': '显示字幕',
'hide-subs': '隐藏字幕',
volume: '音量',
live: '直播',
'video-info': '视频统计信息',
},
'zh-tw': {
'Danmaku is loading': '彈幕載入中',
Top: '頂部',
Bottom: '底部',
Rolling: '滾動',
'Input danmaku, hit Enter': '輸入彈幕Enter 發送',
'About author': '關於作者',
'DPlayer feedback': '播放器意見回饋',
'About DPlayer': '關於 DPlayer 播放器',
Loop: '循環播放',
Speed: '速度',
'Opacity for danmaku': '彈幕透明度',
Normal: '正常',
'Please input danmaku content!': '請輸入彈幕內容啊!',
'Set danmaku color': '設定彈幕顏色',
'Set danmaku type': '設定彈幕類型',
'Show danmaku': '顯示彈幕',
'Video load failed': '影片載入失敗',
'Danmaku load failed': '彈幕載入失敗',
'Danmaku send failed': '彈幕發送失敗',
'Switching to': '正在切換至',
'Switched to': '已經切換至',
quality: '畫質',
FF: '快進',
REW: '快退',
'Unlimited danmaku': '巨量彈幕',
'Send danmaku': '發送彈幕',
Setting: '設定',
'Full screen': '全螢幕',
'Web full screen': '頁面全螢幕',
Send: '發送',
Screenshot: '截圖',
AirPlay: '無線投屏',
ChromeCast: 'ChromeCast',
s: '秒',
'Show subtitle': '顯示字幕',
'Hide subtitle': '隱藏字幕',
Volume: '音量',
Live: '直播',
'Video info': '影片統計訊息',
'danmaku-loading': '彈幕載入中',
top: '頂部',
bottom: '底部',
rolling: '滾動',
'input-danmaku-enter': '輸入彈幕Enter 發送',
'about-author': '關於作者',
'dplayer-feedback': '播放器意見回饋',
'about-dplayer': '關於 DPlayer 播放器',
loop: '循環播放',
speed: '速度',
'opacity-danmaku': '彈幕透明度',
normal: '正常',
'please-input-danmaku': '請輸入彈幕內容啊!',
'set-danmaku-color': '設定彈幕顏色',
'set-danmaku-type': '設定彈幕類型',
'show-danmaku': '顯示彈幕',
'video-failed': '影片載入失敗',
'danmaku-failed': '彈幕載入失敗',
'danmaku-send-failed': '彈幕發送失敗',
'switching-quality': '正在切換至 %q 畫質',
'switched-quality': '已經切換至 %q 畫質',
ff: '快進 %s 秒',
rew: '快退 %s 秒',
'unlimited-danmaku': '巨量彈幕',
'send-danmaku': '發送彈幕',
setting: '設定',
fullscreen: '全螢幕',
'web-fullscreen': '頁面全螢幕',
send: '發送',
screenshot: '截圖',
airplay: '無線投屏',
chromecast: 'ChromeCast',
'show-subs': '顯示字幕',
'hide-subs': '隱藏字幕',
volume: '音量',
live: '直播',
'video-info': '影片統計訊息',
},
'ko-kr': {
'Danmaku is loading': 'Danmaku를 불러오는 중입니다.',
Top: 'Top',
Bottom: 'Bottom',
Rolling: 'Rolling',
'Input danmaku, hit Enter': 'Danmaku를 입력하고 Enter를 누르세요.',
'About author': '만든이',
'DPlayer feedback': '피드백 보내기',
'About DPlayer': 'DPlayer 정보',
Loop: '반복',
Speed: '배속',
'Opacity for danmaku': 'Danmaku 불투명도',
Normal: '표준',
'Please input danmaku content!': 'Danmaku를 입력하세요!',
'Set danmaku color': 'Danmaku 색상',
'Set danmaku type': 'Danmaku 설정',
'Show danmaku': 'Danmaku 표시',
'Video load failed': '비디오를 불러오지 못했습니다.',
'Danmaku load failed': 'Danmaku를 불러오지 못했습니다.',
'Danmaku send failed': 'Danmaku 전송에 실패했습니다.',
'Switching to': '전환',
'Switched to': '전환 됨',
quality: '화질',
FF: '앞으로',
REW: '뒤로',
'Unlimited danmaku': '끝없는 Danmaku',
'Send danmaku': 'Danmaku 보내기',
Setting: '설정',
'Full screen': '전체 화면',
'Web full screen': '웹 내 전체화면',
Send: '보내기',
Screenshot: '화면 캡쳐',
AirPlay: '에어플레이',
s: '초',
'Show subtitle': '자막 보이기',
'Hide subtitle': '자막 숨기기',
'danmaku-loading': 'Danmaku를 불러오는 중입니다.',
top: 'Top',
bottom: 'Bottom',
rolling: 'Rolling',
'input-danmaku-enter': 'Danmaku를 입력하고 Enter를 누르세요.',
'about-author': '만든이',
'dplayer-feedback': '피드백 보내기',
'about-dplayer': 'DPlayer 정보',
loop: '반복',
speed: '배속',
'opacity-danmaku': 'Danmaku 불투명도',
normal: '표준',
'please-input-danmaku': 'Danmaku를 입력하세요!',
'set-danmaku-color': 'Danmaku 색상',
'set-danmaku-type': 'Danmaku 설정',
'show-danmaku': 'Danmaku 표시',
'video-failed': '비디오를 불러오지 못했습니다.',
'danmaku-failed': 'Danmaku를 불러오지 못했습니다.',
'danmaku-send-failed': 'Danmaku 전송에 실패했습니다.',
'Switching to': '',
'Switched to': '',
'switching-quality': '전환 %q 화질',
'switched-quality': '전환 됨 %q 화질',
ff: '앞으로 %s 초',
rew: '뒤로 %s 초',
'unlimited-danmaku': '끝없는 Danmaku',
'send-danmaku': 'Danmaku 보내기',
setting: '설정',
fullscreen: '전체 화면',
'web-fullscreen': '웹 내 전체화면',
send: '보내기',
screenshot: '화면 캡쳐',
airplay: '에어플레이',
chromecast: 'ChromeCast',
'show-subs': '자막 보이기',
'hide-subs': '자막 숨기기',
Volume: '볼륨',
Live: '생방송',
'Video info': '비디오 정보',
live: '생방송',
'video-info': '비디오 정보',
},
de: {
'danmaku-loading': 'Danmaku lädt...',
top: 'Oben',
bottom: 'Unten',
rolling: 'Rollend',
'input-danmaku-enter': 'Drücke Enter nach dem Einfügen vom Danmaku',
'about-author': 'Über den Autor',
'dplayer-feedback': 'DPlayer Feedback',
'about-dplayer': 'Über DPlayer',
loop: 'Wiederholen',
speed: 'Geschwindigkeit',
'opacity-danmaku': 'Transparenz für Danmaku',
normal: 'Normal',
'please-input-danmaku': 'Bitte Danmaku Inhalt eingeben!',
'set-danmaku-color': 'Danmaku Farbe festlegen',
'set-danmaku-type': 'Danmaku Typ festlegen',
'show-danmaku': 'Zeige Danmaku',
'video-failed': 'Das Video konnte nicht geladen werden',
'danmaku-failed': 'Danmaku konnte nicht geladen werden',
'danmaku-send-failed': 'Das senden von Danmaku ist fehgeschlagen',
'switching-quality': 'Wechsle zur %q Qualität',
'switched-quality': 'Zur %q Qualität gewechselt',
ff: '%s s Vorwärts',
rew: '%s s Zurück',
'unlimited-danmaku': 'Unlimitiertes Danmaku',
'send-danmaku': 'Sende Danmaku',
setting: 'Einstellungen',
fullscreen: 'Vollbild',
'web-fullscreen': 'Browser Vollbild',
send: 'Senden',
screenshot: 'Screenshot',
airplay: 'AirPlay',
'show-subs': 'Zeige Untertitel',
chromecast: 'ChromeCast',
'hide-subs': 'Verstecke Untertitel',
volume: 'Lautstärke',
live: 'Live',
'video-info': 'Video Info',
},
};
export default i18n;
export { i18n };

View File

@ -52,13 +52,13 @@ export default (options) => {
options.contextmenu = options.contextmenu.concat([
{
text: 'Video info',
key: 'video-info',
click: (player) => {
player.infoPanel.triggle();
},
},
{
text: 'About author',
key: 'about-author',
link: 'https://diygod.me',
},
{

View File

@ -2,7 +2,7 @@ import Promise from 'promise-polyfill';
import utils from './utils';
import handleOption from './options';
import i18n from './i18n';
import { i18n } from './i18n';
import Template from './template';
import Icons from './icons';
import Danmaku from './danmaku';
@ -156,9 +156,9 @@ class DPlayer {
time = Math.min(time, this.video.duration);
}
if (this.video.currentTime < time) {
this.notice(`${this.tran('FF')} ${(time - this.video.currentTime).toFixed(0)} ${this.tran('s')}`);
this.notice(`${this.tran('ff').replace('%s', (time - this.video.currentTime).toFixed(0))}`);
} else if (this.video.currentTime > time) {
this.notice(`${this.tran('REW')} ${(this.video.currentTime - time).toFixed(0)} ${this.tran('s')}`);
this.notice(`${this.tran('rew').replace('%s', (this.video.currentTime - time).toFixed(0))}`);
}
this.video.currentTime = time;
@ -255,7 +255,7 @@ class DPlayer {
this.user.set('volume', percentage);
}
if (!nonotice) {
this.notice(`${this.tran('Volume')} ${(percentage * 100).toFixed(0)}%`);
this.notice(`${this.tran('volume')} ${(percentage * 100).toFixed(0)}%`);
}
this.video.volume = percentage;
@ -468,7 +468,7 @@ class DPlayer {
// Not a video load error, may be poster load failed, see #307
return;
}
this.tran && this.notice && this.type !== 'webtorrent' && this.notice(this.tran('Video load failed'), -1);
this.tran && this.notice && this.type !== 'webtorrent' && this.notice(this.tran('video-failed'), -1);
});
// video end
@ -549,7 +549,7 @@ class DPlayer {
this.video = videoEle;
this.initVideo(this.video, this.quality.type || this.options.video.type);
this.seek(this.prevVideo.currentTime);
this.notice(`${this.tran('Switching to')} ${this.quality.name} ${this.tran('quality')}`, -1);
this.notice(`${this.tran('switching-quality').replace('%q', this.quality.name)}`, -1);
this.events.trigger('quality_start', this.quality);
this.on('canplay', () => {
@ -564,7 +564,7 @@ class DPlayer {
this.video.play();
}
this.prevVideo = null;
this.notice(`${this.tran('Switched to')} ${this.quality.name} ${this.tran('quality')}`);
this.notice(`${this.tran('switched-quality').replace('%q', this.quality.name)}`);
this.switchingQuality = false;
this.events.trigger('quality_end');

View File

@ -13,7 +13,7 @@
<div class="dplayer-bezel">
<span class="dplayer-bezel-icon"></span>
{{ if options.danmaku }}
<span class="dplayer-danloading">{{ tran('Danmaku is loading') }}</span>
<span class="dplayer-danloading">{{ tran('danmaku-loading') }}</span>
{{ /if }}
<span class="diplayer-loading-icon">{{@ icons.loading }}</span>
</div>
@ -21,12 +21,12 @@
<div class="dplayer-controller-mask"></div>
<div class="dplayer-controller">
<div class="dplayer-icons dplayer-comment-box">
<button class="dplayer-icon dplayer-comment-setting-icon" data-balloon="{{ tran('Setting') }}" data-balloon-pos="up">
<button class="dplayer-icon dplayer-comment-setting-icon" data-balloon="{{ tran('setting') }}" data-balloon-pos="up">
<span class="dplayer-icon-content">{{@ icons.pallette }}</span>
</button>
<div class="dplayer-comment-setting-box">
<div class="dplayer-comment-setting-color">
<div class="dplayer-comment-setting-title">{{ tran('Set danmaku color') }}</div>
<div class="dplayer-comment-setting-title">{{ tran('set-danmaku-color') }}</div>
<label>
<input type="radio" name="dplayer-danmaku-color-{{ index }}" value="#fff" checked>
<span style="background: #fff;"></span>
@ -53,23 +53,23 @@
</label>
</div>
<div class="dplayer-comment-setting-type">
<div class="dplayer-comment-setting-title">{{ tran('Set danmaku type') }}</div>
<div class="dplayer-comment-setting-title">{{ tran('set-danmaku-type') }}</div>
<label>
<input type="radio" name="dplayer-danmaku-type-{{ index }}" value="1">
<span>{{ tran('Top') }}</span>
<span>{{ tran('top') }}</span>
</label>
<label>
<input type="radio" name="dplayer-danmaku-type-{{ index }}" value="0" checked>
<span>{{ tran('Rolling') }}</span>
<span>{{ tran('rolling') }}</span>
</label>
<label>
<input type="radio" name="dplayer-danmaku-type-{{ index }}" value="2">
<span>{{ tran('Bottom') }}</span>
<span>{{ tran('bottom') }}</span>
</label>
</div>
</div>
<input class="dplayer-comment-input" type="text" placeholder="{{ tran('Input danmaku, hit Enter') }}" maxlength="30">
<button class="dplayer-icon dplayer-send-icon" data-balloon="{{ tran('Send') }}" data-balloon-pos="up">
<input class="dplayer-comment-input" type="text" placeholder="{{ tran('input-danmaku-enter') }}" maxlength="30">
<button class="dplayer-icon dplayer-send-icon" data-balloon="{{ tran('send') }}" data-balloon-pos="up">
<span class="dplayer-icon-content">{{@ icons.send }}</span>
</button>
</div>
@ -94,7 +94,7 @@
<span class="dplayer-dtime">0:00</span>
</span>
{{ if options.live }}
<span class="dplayer-live-badge"><span class="dplayer-live-dot" style="background: {{ options.theme }};"></span>{{ tran('Live') }}</span>
<span class="dplayer-live-badge"><span class="dplayer-live-dot" style="background: {{ options.theme }};"></span>{{ tran('live') }}</span>
{{ /if }}
</div>
<div class="dplayer-icons dplayer-icons-right">
@ -111,65 +111,65 @@
</div>
{{ /if }}
{{ if options.screenshot }}
<div class="dplayer-icon dplayer-camera-icon" data-balloon="{{ tran('Screenshot') }}" data-balloon-pos="up">
<div class="dplayer-icon dplayer-camera-icon" data-balloon="{{ tran('screenshot') }}" data-balloon-pos="up">
<span class="dplayer-icon-content">{{@ icons.camera }}</span>
</div>
{{ /if }}
{{ if options.airplay }}
<div class="dplayer-icon dplayer-airplay-icon" data-balloon="{{ tran('AirPlay') }}" data-balloon-pos="up">
<div class="dplayer-icon dplayer-airplay-icon" data-balloon="{{ tran('airplay') }}" data-balloon-pos="up">
<span class="dplayer-icon-content">{{@ icons.airplay }}</span>
</div>
{{ /if }}
{{ if options.chromecast }}
<div class="dplayer-icon dplayer-chromecast-icon" data-balloon="{{ tran('ChromeCast') }}" data-balloon-pos="up">
<div class="dplayer-icon dplayer-chromecast-icon" data-balloon="{{ tran('chromecast') }}" data-balloon-pos="up">
<span class="dplayer-icon-content">{{@ icons.chromecast }}</span>
</div>
{{ /if }}
<div class="dplayer-comment">
<button class="dplayer-icon dplayer-comment-icon" data-balloon="{{ tran('Send danmaku') }}" data-balloon-pos="up">
<button class="dplayer-icon dplayer-comment-icon" data-balloon="{{ tran('send-danmaku') }}" data-balloon-pos="up">
<span class="dplayer-icon-content">{{@ icons.comment }}</span>
</button>
</div>
{{ if options.subtitle }}
<div class="dplayer-subtitle-btn">
<button class="dplayer-icon dplayer-subtitle-icon" data-balloon="{{ tran('Hide subtitle') }}" data-balloon-pos="up">
<button class="dplayer-icon dplayer-subtitle-icon" data-balloon="{{ tran('hide-subs') }}" data-balloon-pos="up">
<span class="dplayer-icon-content">{{@ icons.subtitle }}</span>
</button>
</div>
{{ /if }}
<div class="dplayer-setting">
<button class="dplayer-icon dplayer-setting-icon" data-balloon="{{ tran('Setting') }}" data-balloon-pos="up">
<button class="dplayer-icon dplayer-setting-icon" data-balloon="{{ tran('setting') }}" data-balloon-pos="up">
<span class="dplayer-icon-content">{{@ icons.setting }}</span>
</button>
<div class="dplayer-setting-box">
<div class="dplayer-setting-origin-panel">
<div class="dplayer-setting-item dplayer-setting-speed">
<span class="dplayer-label">{{ tran('Speed') }}</span>
<span class="dplayer-label">{{ tran('speed') }}</span>
<div class="dplayer-toggle">{{@ icons.right }}</div>
</div>
<div class="dplayer-setting-item dplayer-setting-loop">
<span class="dplayer-label">{{ tran('Loop') }}</span>
<span class="dplayer-label">{{ tran('loop') }}</span>
<div class="dplayer-toggle">
<input class="dplayer-toggle-setting-input" type="checkbox" name="dplayer-toggle">
<label for="dplayer-toggle"></label>
</div>
</div>
<div class="dplayer-setting-item dplayer-setting-showdan">
<span class="dplayer-label">{{ tran('Show danmaku') }}</span>
<span class="dplayer-label">{{ tran('show-danmaku') }}</span>
<div class="dplayer-toggle">
<input class="dplayer-showdan-setting-input" type="checkbox" name="dplayer-toggle-dan">
<label for="dplayer-toggle-dan"></label>
</div>
</div>
<div class="dplayer-setting-item dplayer-setting-danunlimit">
<span class="dplayer-label">{{ tran('Unlimited danmaku') }}</span>
<span class="dplayer-label">{{ tran('unlimited-danmaku') }}</span>
<div class="dplayer-toggle">
<input class="dplayer-danunlimit-setting-input" type="checkbox" name="dplayer-toggle-danunlimit">
<label for="dplayer-toggle-danunlimit"></label>
</div>
</div>
<div class="dplayer-setting-item dplayer-setting-danmaku">
<span class="dplayer-label">{{ tran('Opacity for danmaku') }}</span>
<span class="dplayer-label">{{ tran('opacity-danmaku') }}</span>
<div class="dplayer-danmaku-bar-wrap">
<div class="dplayer-danmaku-bar">
<div class="dplayer-danmaku-bar-inner">
@ -182,17 +182,17 @@
<div class="dplayer-setting-speed-panel">
{{ each options.playbackSpeed }}
<div class="dplayer-setting-speed-item" data-speed="{{ $value }}">
<span class="dplayer-label">{{ $value === 1 ? tran('Normal') : $value }}</span>
<span class="dplayer-label">{{ $value === 1 ? tran('normal') : $value }}</span>
</div>
{{ /each }}
</div>
</div>
</div>
<div class="dplayer-full">
<button class="dplayer-icon dplayer-full-in-icon" data-balloon="{{ tran('Web full screen') }}" data-balloon-pos="up">
<button class="dplayer-icon dplayer-full-in-icon" data-balloon="{{ tran('web-fullscreen') }}" data-balloon-pos="up">
<span class="dplayer-icon-content">{{@ icons.fullWeb }}</span>
</button>
<button class="dplayer-icon dplayer-full-icon" data-balloon="{{ tran('Full screen') }}" data-balloon-pos="up">
<button class="dplayer-icon dplayer-full-icon" data-balloon="{{ tran('fullscreen') }}" data-balloon-pos="up">
<span class="dplayer-icon-content">{{@ icons.full }}</span>
</button>
</div>
@ -252,7 +252,7 @@
<div class="dplayer-menu">
{{ each options.contextmenu }}
<div class="dplayer-menu-item">
<a{{ if $value.link }} target="_blank"{{ /if }} href="{{ $value.link || 'javascript:void(0);' }}">{{ tran($value.text) }}</a>
<a{{ if $value.link }} target="_blank"{{ /if }} href="{{ $value.link || 'javascript:void(0);' }}">{{ if $value.key }} {{ tran($value.key) }}{{ /if }}{{ if $value.text }} {{$value.text}}{{ /if }}</a>
</div>
{{ /each }}
</div>