aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/locale/translations/de_DE.json11
-rw-r--r--internal/locale/translations/el_EL.json11
-rw-r--r--internal/locale/translations/en_US.json11
-rw-r--r--internal/locale/translations/es_ES.json11
-rw-r--r--internal/locale/translations/fi_FI.json11
-rw-r--r--internal/locale/translations/fr_FR.json11
-rw-r--r--internal/locale/translations/hi_IN.json11
-rw-r--r--internal/locale/translations/id_ID.json11
-rw-r--r--internal/locale/translations/it_IT.json11
-rw-r--r--internal/locale/translations/ja_JP.json11
-rw-r--r--internal/locale/translations/nl_NL.json11
-rw-r--r--internal/locale/translations/pl_PL.json11
-rw-r--r--internal/locale/translations/pt_BR.json11
-rw-r--r--internal/locale/translations/ru_RU.json11
-rw-r--r--internal/locale/translations/tr_TR.json11
-rw-r--r--internal/locale/translations/uk_UA.json11
-rw-r--r--internal/locale/translations/zh_CN.json11
-rw-r--r--internal/locale/translations/zh_TW.json11
-rw-r--r--internal/template/templates/common/enclosure_media_controls.html18
-rw-r--r--internal/template/templates/views/entry.html8
-rw-r--r--internal/ui/static/css/common.css33
-rw-r--r--internal/ui/static/js/app.js50
-rw-r--r--internal/ui/static/js/bootstrap.js14
23 files changed, 298 insertions, 23 deletions
diff --git a/internal/locale/translations/de_DE.json b/internal/locale/translations/de_DE.json
index c49a27f6..b8cceb46 100644
--- a/internal/locale/translations/de_DE.json
+++ b/internal/locale/translations/de_DE.json
@@ -529,5 +529,14 @@
"error.unable_to_detect_rssbridge": "Abonnement kann nicht durch RSS-Bridge erkannt werden: %v.",
"error.feed_format_not_detected": "Das Format des Abonnements kann nicht erkannt werden: %v.",
"form.prefs.label.media_playback_rate": "Wiedergabegeschwindigkeit von Audio/Video",
- "error.settings_media_playback_rate_range": "Die Wiedergabegeschwindigkeit liegt außerhalb des Bereichs"
+ "error.settings_media_playback_rate_range": "Die Wiedergabegeschwindigkeit liegt außerhalb des Bereichs",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/el_EL.json b/internal/locale/translations/el_EL.json
index 94d74149..42758fb7 100644
--- a/internal/locale/translations/el_EL.json
+++ b/internal/locale/translations/el_EL.json
@@ -529,5 +529,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "Ταχύτητα αναπαραγωγής του ήχου/βίντεο",
- "error.settings_media_playback_rate_range": "Η ταχύτητα αναπαραγωγής είναι εκτός εύρους"
+ "error.settings_media_playback_rate_range": "Η ταχύτητα αναπαραγωγής είναι εκτός εύρους",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/en_US.json b/internal/locale/translations/en_US.json
index 77b73778..61e14f8e 100644
--- a/internal/locale/translations/en_US.json
+++ b/internal/locale/translations/en_US.json
@@ -529,5 +529,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "Playback speed of the audio/video",
- "error.settings_media_playback_rate_range": "Playback speed is out of range"
+ "error.settings_media_playback_rate_range": "Playback speed is out of range",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/es_ES.json b/internal/locale/translations/es_ES.json
index d4669b39..cdb4b9df 100644
--- a/internal/locale/translations/es_ES.json
+++ b/internal/locale/translations/es_ES.json
@@ -529,5 +529,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "Velocidad de reproducción del audio/vídeo",
- "error.settings_media_playback_rate_range": "La velocidad de reproducción está fuera de rango"
+ "error.settings_media_playback_rate_range": "La velocidad de reproducción está fuera de rango",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/fi_FI.json b/internal/locale/translations/fi_FI.json
index 6b2f2fca..922b6356 100644
--- a/internal/locale/translations/fi_FI.json
+++ b/internal/locale/translations/fi_FI.json
@@ -529,5 +529,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "Äänen/videon toistonopeus",
- "error.settings_media_playback_rate_range": "Toistonopeus on alueen ulkopuolella"
+ "error.settings_media_playback_rate_range": "Toistonopeus on alueen ulkopuolella",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/fr_FR.json b/internal/locale/translations/fr_FR.json
index fb2982fa..c533a15c 100644
--- a/internal/locale/translations/fr_FR.json
+++ b/internal/locale/translations/fr_FR.json
@@ -529,5 +529,14 @@
"error.unable_to_detect_rssbridge": "Impossible de détecter un flux RSS en utilisant RSS-Bridge: %v.",
"error.feed_format_not_detected": "Impossible de détecter le format du flux : %v.",
"form.prefs.label.media_playback_rate": "Vitesse de lecture de l'audio/vidéo",
- "error.settings_media_playback_rate_range": "La vitesse de lecture est hors limites"
+ "error.settings_media_playback_rate_range": "La vitesse de lecture est hors limites",
+ "enclosure_media_controls.seek" : "Avancer/Reculer :",
+ "enclosure_media_controls.seek.title" : "Avancer/Reculer de %s seconds",
+ "enclosure_media_controls.speed" : "Vitesse :",
+ "enclosure_media_controls.speed.faster" : "Accélérer",
+ "enclosure_media_controls.speed.faster.title" : "Accélérer de %sx",
+ "enclosure_media_controls.speed.slower" : "Ralentir",
+ "enclosure_media_controls.speed.slower.title" : "Ralentir de %sx",
+ "enclosure_media_controls.speed.reset" : "Réinitialiser",
+ "enclosure_media_controls.speed.reset.title" : "Réinitialiser la vitesse de lecture à 1x"
}
diff --git a/internal/locale/translations/hi_IN.json b/internal/locale/translations/hi_IN.json
index ef7c0c04..b857b1c9 100644
--- a/internal/locale/translations/hi_IN.json
+++ b/internal/locale/translations/hi_IN.json
@@ -529,5 +529,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "ऑडियो/वीडियो की प्लेबैक गति",
- "error.settings_media_playback_rate_range": "प्लेबैक गति सीमा से बाहर है"
+ "error.settings_media_playback_rate_range": "प्लेबैक गति सीमा से बाहर है",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/id_ID.json b/internal/locale/translations/id_ID.json
index 3f1e3cd3..a0ac7880 100644
--- a/internal/locale/translations/id_ID.json
+++ b/internal/locale/translations/id_ID.json
@@ -512,5 +512,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "Kecepatan pemutaran audio/video",
- "error.settings_media_playback_rate_range": "Kecepatan pemutaran di luar jangkauan"
+ "error.settings_media_playback_rate_range": "Kecepatan pemutaran di luar jangkauan",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/it_IT.json b/internal/locale/translations/it_IT.json
index e9385c7c..e3b12225 100644
--- a/internal/locale/translations/it_IT.json
+++ b/internal/locale/translations/it_IT.json
@@ -529,5 +529,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "Velocità di riproduzione dell'audio/video",
- "error.settings_media_playback_rate_range": "La velocità di riproduzione non rientra nell'intervallo"
+ "error.settings_media_playback_rate_range": "La velocità di riproduzione non rientra nell'intervallo",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/ja_JP.json b/internal/locale/translations/ja_JP.json
index efd2d37d..55f6de83 100644
--- a/internal/locale/translations/ja_JP.json
+++ b/internal/locale/translations/ja_JP.json
@@ -512,5 +512,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "オーディオ/ビデオの再生速度",
- "error.settings_media_playback_rate_range": "再生速度が範囲外"
+ "error.settings_media_playback_rate_range": "再生速度が範囲外",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/nl_NL.json b/internal/locale/translations/nl_NL.json
index d9141819..c9b235e2 100644
--- a/internal/locale/translations/nl_NL.json
+++ b/internal/locale/translations/nl_NL.json
@@ -529,5 +529,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "Afspeelsnelheid van de audio/video",
- "error.settings_media_playback_rate_range": "Afspeelsnelheid is buiten bereik"
+ "error.settings_media_playback_rate_range": "Afspeelsnelheid is buiten bereik",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/pl_PL.json b/internal/locale/translations/pl_PL.json
index 3b39301d..78c49876 100644
--- a/internal/locale/translations/pl_PL.json
+++ b/internal/locale/translations/pl_PL.json
@@ -546,5 +546,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "Prędkość odtwarzania audio/wideo",
- "error.settings_media_playback_rate_range": "Prędkość odtwarzania jest poza zakresem"
+ "error.settings_media_playback_rate_range": "Prędkość odtwarzania jest poza zakresem",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/pt_BR.json b/internal/locale/translations/pt_BR.json
index 7c639f5b..dd9dca9c 100644
--- a/internal/locale/translations/pt_BR.json
+++ b/internal/locale/translations/pt_BR.json
@@ -529,5 +529,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "Velocidade de reprodução do áudio/vídeo",
- "error.settings_media_playback_rate_range": "A velocidade de reprodução está fora do intervalo"
+ "error.settings_media_playback_rate_range": "A velocidade de reprodução está fora do intervalo",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/ru_RU.json b/internal/locale/translations/ru_RU.json
index 6327c09f..636ef54e 100644
--- a/internal/locale/translations/ru_RU.json
+++ b/internal/locale/translations/ru_RU.json
@@ -546,5 +546,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "Скорость воспроизведения аудио/видео",
- "error.settings_media_playback_rate_range": "Скорость воспроизведения выходит за пределы диапазона"
+ "error.settings_media_playback_rate_range": "Скорость воспроизведения выходит за пределы диапазона",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/tr_TR.json b/internal/locale/translations/tr_TR.json
index 4fc999a2..87a67025 100644
--- a/internal/locale/translations/tr_TR.json
+++ b/internal/locale/translations/tr_TR.json
@@ -496,5 +496,14 @@
"time_elapsed.years": ["%d yıl önce", "%d yıl önce"],
"time_elapsed.yesterday": "dün",
"tooltip.keyboard_shortcuts": "Klavye Kısayolu: %s",
- "tooltip.logged_user": "%s olarak giriş yapıldı"
+ "tooltip.logged_user": "%s olarak giriş yapıldı",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/uk_UA.json b/internal/locale/translations/uk_UA.json
index 832a1471..221a4ca9 100644
--- a/internal/locale/translations/uk_UA.json
+++ b/internal/locale/translations/uk_UA.json
@@ -546,5 +546,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "Швидкість відтворення аудіо/відео",
- "error.settings_media_playback_rate_range": "Швидкість відтворення виходить за межі діапазону"
+ "error.settings_media_playback_rate_range": "Швидкість відтворення виходить за межі діапазону",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/zh_CN.json b/internal/locale/translations/zh_CN.json
index b32a270a..d1797c24 100644
--- a/internal/locale/translations/zh_CN.json
+++ b/internal/locale/translations/zh_CN.json
@@ -512,5 +512,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "音频/视频的播放速度",
- "error.settings_media_playback_rate_range": "播放速度超出范围"
+ "error.settings_media_playback_rate_range": "播放速度超出范围",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/locale/translations/zh_TW.json b/internal/locale/translations/zh_TW.json
index 39504b73..35be9e2b 100644
--- a/internal/locale/translations/zh_TW.json
+++ b/internal/locale/translations/zh_TW.json
@@ -512,5 +512,14 @@
"error.unable_to_detect_rssbridge": "Unable to detect feed using RSS-Bridge: %v.",
"error.feed_format_not_detected": "Unable to detect feed format: %v.",
"form.prefs.label.media_playback_rate": "音訊/視訊的播放速度",
- "error.settings_media_playback_rate_range": "播放速度超出範圍"
+ "error.settings_media_playback_rate_range": "播放速度超出範圍",
+ "enclosure_media_controls.seek" : "Seek:",
+ "enclosure_media_controls.seek.title" : "Seek %s seconds",
+ "enclosure_media_controls.speed" : "Speed:",
+ "enclosure_media_controls.speed.faster" : "Faster",
+ "enclosure_media_controls.speed.faster.title" : "Faster by %sx",
+ "enclosure_media_controls.speed.slower" : "Slower",
+ "enclosure_media_controls.speed.slower.title" : "Slower by %sx",
+ "enclosure_media_controls.speed.reset" : "Reset",
+ "enclosure_media_controls.speed.reset.title" : "Reset speed to 1x"
}
diff --git a/internal/template/templates/common/enclosure_media_controls.html b/internal/template/templates/common/enclosure_media_controls.html
new file mode 100644
index 00000000..208b3933
--- /dev/null
+++ b/internal/template/templates/common/enclosure_media_controls.html
@@ -0,0 +1,18 @@
+{{ define "enclosure_media_controls" }}
+<div class="media-controls">
+ <div class="media-seek-control">
+ <div class="media-control-label">{{ t "enclosure_media_controls.seek" }} </div>
+ <button class="page-button" data-enclosure-id="{{.ID}}" data-enclosure-action="seek" data-action-value="-30" title="{{ t "enclosure_media_controls.seek.title" "-30" }}" ><span class="icon-label" >-30s</span></button>
+ <button class="page-button" data-enclosure-id="{{.ID}}" data-enclosure-action="seek" data-action-value="-10" title="{{ t "enclosure_media_controls.seek.title" "-10" }}" ><span class="icon-label" >-10s</span></button>
+ <button class="page-button" data-enclosure-id="{{.ID}}" data-enclosure-action="seek" data-action-value="+10" title="{{ t "enclosure_media_controls.seek.title" "+10" }}" ><span class="icon-label" >+10s</span></button>
+ <button class="page-button" data-enclosure-id="{{.ID}}" data-enclosure-action="seek" data-action-value="+30" title="{{ t "enclosure_media_controls.seek.title" "+30" }}" ><span class="icon-label" >+30s</span></button>
+ </div>
+ <div class="media-speed-control">
+
+ <div class="media-control-label">{{ t "enclosure_media_controls.speed" }} (<span class="speed-indicator" data-enclosure-id="{{.ID}}">x.xxx</span>)</div> <!-- Need JS to display the current speed unfortunately -->
+ <button class="page-button" data-enclosure-id="{{.ID}}" data-enclosure-action="speed" data-action-value="-0.25" title="{{ t "enclosure_media_controls.speed.slower.title" "0.25" }}"><span class="icon-label" >{{ t "enclosure_media_controls.speed.slower" }}</span></button>
+ <button class="page-button" data-enclosure-id="{{.ID}}" data-enclosure-action="speed-reset" data-action-value="1" title="{{ t "enclosure_media_controls.speed.reset.title"}}"><span class="icon-label" >{{ t "enclosure_media_controls.speed.reset" }}</span></button>
+ <button class="page-button" data-enclosure-id="{{.ID}}" data-enclosure-action="speed" data-action-value="+0.25" title="{{ t "enclosure_media_controls.speed.faster.title" "0.25" }}"><span class="icon-label" >{{ t "enclosure_media_controls.speed.faster" }}</span></button>
+ </div>
+</div>
+{{ end }}
diff --git a/internal/template/templates/views/entry.html b/internal/template/templates/views/entry.html
index 48f3c5fe..85618954 100644
--- a/internal/template/templates/views/entry.html
+++ b/internal/template/templates/views/entry.html
@@ -174,6 +174,7 @@
data-last-position="{{ .MediaProgression }}"
{{ if $.user.MediaPlaybackRate }}data-playback-rate="{{ $.user.MediaPlaybackRate }}"{{ end }}
data-save-url="{{ route "saveEnclosureProgression" "enclosureID" .ID }}"
+ data-enclosure-id="{{.ID}}"
>
{{ if (and $.user (mustBeProxyfied "audio")) }}
<source src="{{ proxyURL .URL }}" type="{{ .Html5MimeType }}">
@@ -181,6 +182,7 @@
<source src="{{ .URL | safeURL }}" type="{{ .Html5MimeType }}">
{{ end }}
</audio>
+ {{ template "enclosure_media_controls" . }}
</div>
{{ else if hasPrefix .MimeType "video/" }}
<div class="enclosure-video">
@@ -188,6 +190,7 @@
data-last-position="{{ .MediaProgression }}"
{{ if $.user.MediaPlaybackRate }}data-playback-rate="{{ $.user.MediaPlaybackRate }}"{{ end }}
data-save-url="{{ route "saveEnclosureProgression" "enclosureID" .ID }}"
+ data-enclosure-id="{{.ID}}"
>
{{ if (and $.user (mustBeProxyfied "video")) }}
<source src="{{ proxyURL .URL }}" type="{{ .Html5MimeType }}">
@@ -195,6 +198,7 @@
<source src="{{ .URL | safeURL }}" type="{{ .Html5MimeType }}">
{{ end }}
</video>
+ {{ template "enclosure_media_controls" . }}
</div>
{{ end }}
{{ end }}
@@ -218,6 +222,7 @@
data-last-position="{{ .MediaProgression }}"
{{ if $.user.MediaPlaybackRate }}data-playback-rate="{{ $.user.MediaPlaybackRate }}"{{ end }}
data-save-url="{{ route "saveEnclosureProgression" "enclosureID" .ID }}"
+ data-enclosure-id="{{.ID}}"
>
{{ if (and $.user (mustBeProxyfied "audio")) }}
<source src="{{ proxyURL .URL }}" type="{{ .Html5MimeType }}">
@@ -225,6 +230,7 @@
<source src="{{ .URL | safeURL }}" type="{{ .Html5MimeType }}">
{{ end }}
</audio>
+ {{ template "enclosure_media_controls" . }}
</div>
{{ else if hasPrefix .MimeType "video/" }}
<div class="enclosure-video">
@@ -232,6 +238,7 @@
data-last-position="{{ .MediaProgression }}"
{{ if $.user.MediaPlaybackRate }}data-playback-rate="{{ $.user.MediaPlaybackRate }}"{{ end }}
data-save-url="{{ route "saveEnclosureProgression" "enclosureID" .ID }}"
+ data-enclosure-id="{{.ID}}"
>
{{ if (and $.user (mustBeProxyfied "video")) }}
<source src="{{ proxyURL .URL }}" type="{{ .Html5MimeType }}">
@@ -239,6 +246,7 @@
<source src="{{ .URL | safeURL }}" type="{{ .Html5MimeType }}">
{{ end }}
</video>
+ {{ template "enclosure_media_controls" . }}
</div>
{{ else if hasPrefix .MimeType "image/" }}
<div class="enclosure-image">
diff --git a/internal/ui/static/css/common.css b/internal/ui/static/css/common.css
index 1a3c3ee8..a27aadae 100644
--- a/internal/ui/static/css/common.css
+++ b/internal/ui/static/css/common.css
@@ -1215,6 +1215,39 @@ audio, video {
width: 100%;
}
+.media-controls{
+ font-size: .9em;
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.media-controls .media-control-label{
+ line-height: 1em;
+}
+
+.media-controls>div{
+ display: flex;
+ flex-wrap: nowrap;
+ justify-content:center;
+ min-width: 50%;
+ align-items: center;
+}
+
+.media-controls>div>*{
+ padding-left:12px;
+}
+
+.media-controls>div>*:first-child{
+ padding-left:0;
+}
+
+.media-controls span.speed-indicator{
+ /*monospace to ensure constant width even when value change. JS ensure the value is always on 4 characters (in most cases)
+ This reduce ui flickering due to element moving around a bit
+ */
+ font-family: monospace;
+}
+
.integration-form summary {
font-weight: 700;
}
diff --git a/internal/ui/static/js/app.js b/internal/ui/static/js/app.js
index 02911194..03f2880e 100644
--- a/internal/ui/static/js/app.js
+++ b/internal/ui/static/js/app.js
@@ -446,8 +446,8 @@ function goToPage(page, fallbackSelf) {
}
/**
- *
- * @param {(number|event)} offset - many items to jump for focus.
+ *
+ * @param {(number|event)} offset - many items to jump for focus.
*/
function goToPrevious(offset) {
if (offset instanceof KeyboardEvent) {
@@ -461,8 +461,8 @@ function goToPrevious(offset) {
}
/**
- *
- * @param {(number|event)} offset - How many items to jump for focus.
+ *
+ * @param {(number|event)} offset - How many items to jump for focus.
*/
function goToNext(offset) {
if (offset instanceof KeyboardEvent) {
@@ -521,7 +521,7 @@ function goToListItem(offset) {
items[i].classList.remove("current-item");
// By default adjust selection by offset
- let itemOffset = (i + offset + items.length) % items.length;
+ let itemOffset = (i + offset + items.length) % items.length;
// Allow jumping to top or bottom
if (offset == TOP) {
itemOffset = 0;
@@ -742,3 +742,43 @@ function getCsrfToken() {
return "";
}
+
+/**
+ * Handle all clicks on media player controls button on enclosures.
+ * Will change the current speed and position of the player accordingly.
+ * Will not save anything, all is done client-side, however, changing the position
+ * will trigger the handlePlayerProgressionSave and save the new position backends side.
+ * @param {Element} button
+ */
+function handleMediaControl(button) {
+ const action = button.dataset.enclosureAction;
+ const value = parseFloat(button.dataset.actionValue);
+ const targetEnclosureId = button.dataset.enclosureId;
+ const enclosures = document.querySelectorAll(`audio[data-enclosure-id="${targetEnclosureId}"],video[data-enclosure-id="${targetEnclosureId}"]`);
+ const speedIndicator = document.querySelectorAll(`span.speed-indicator[data-enclosure-id="${targetEnclosureId}"]`);
+ enclosures.forEach((enclosure) => {
+ switch (action) {
+ case "seek":
+ enclosure.currentTime = enclosure.currentTime + value > 0 ? enclosure.currentTime + value : 0;
+ break;
+ case "speed":
+ // I set a floor speed of 0.25 to avoid too slow speed where it gives the impression it stopped.
+ // 0.25 was chosen because it will allow to get back to 1x in two "faster" click, and lower value with same property would be 0.
+ enclosure.playbackRate = Math.max(0.25, enclosure.playbackRate + value);
+ speedIndicator.forEach((speedI) => {
+ // Two digit precision to ensure we always have the same number of characters (4) to avoid controls moving when clicking buttons because of more or less characters.
+ // The trick only work on rate less than 10, but it feels an acceptable tread of considering the feature
+ speedI.innerText = `${enclosure.playbackRate.toFixed(2)}x`;
+ });
+ break;
+ case "speed-reset":
+ enclosure.playbackRate = value ;
+ speedIndicator.forEach((speedI) => {
+ // Two digit precision to ensure we always have the same number of characters (4) to avoid controls moving when clicking buttons because of more or less characters.
+ // The trick only work on rate less than 10, but it feels an acceptable tread of considering the feature
+ speedI.innerText = `${enclosure.playbackRate.toFixed(2)}x`;
+ });
+ break;
+ }
+ });
+}
diff --git a/internal/ui/static/js/bootstrap.js b/internal/ui/static/js/bootstrap.js
index 44d6e716..d78a9d41 100644
--- a/internal/ui/static/js/bootstrap.js
+++ b/internal/ui/static/js/bootstrap.js
@@ -167,6 +167,20 @@ document.addEventListener("DOMContentLoaded", () => {
playbackRateElements.forEach((element) => {
if (element.dataset.playbackRate) {
element.playbackRate = element.dataset.playbackRate;
+ if (element.dataset.enclosureId){
+ // In order to display properly the speed we need to do it on bootstrap.
+ // Could not do it backend side because I didn't know how to do it because of the template inclusion and
+ // the way the initial playback speed is handled. See enclosure_media_controls.html if you want to try to fix this
+ document.querySelectorAll(`span.speed-indicator[data-enclosure-id="${element.dataset.enclosureId}"]`).forEach((speedI)=>{
+ speedI.innerText = `${element.dataset.playbackRate}x`;
+ });
+ }
}
});
+
+ // Set enclosure media controls handlers
+ const mediaControlsElements = document.querySelectorAll("button[data-enclosure-action]");
+ mediaControlsElements.forEach((element) => {
+ element.addEventListener("click", () => handleMediaControl(element));
+ });
});