Add reading time for entries
This commit is contained in:
parent
499fb1f7df
commit
ee5a8a05c9
25 changed files with 813 additions and 653 deletions
|
@ -12,7 +12,7 @@ import (
|
|||
"miniflux.app/logger"
|
||||
)
|
||||
|
||||
const schemaVersion = 32
|
||||
const schemaVersion = 33
|
||||
|
||||
// Migrate executes database migrations.
|
||||
func Migrate(db *sql.DB) {
|
||||
|
|
|
@ -185,6 +185,7 @@ create index entries_user_feed_idx on entries (user_id, feed_id);
|
|||
"schema_version_31": `alter table feeds add column ignore_http_cache bool default false;`,
|
||||
"schema_version_32": `alter table users add column entries_per_page int default 100;
|
||||
`,
|
||||
"schema_version_33": `alter table users add column show_reading_time boolean default 't';`,
|
||||
"schema_version_4": `create type entry_sorting_direction as enum('asc', 'desc');
|
||||
alter table users add column entry_direction entry_sorting_direction default 'asc';
|
||||
`,
|
||||
|
@ -240,6 +241,7 @@ var SqlMapChecksums = map[string]string{
|
|||
"schema_version_30": "3ec48a9b2e7a0fc32c85f31652f723565c34213f5f2d7e5e5076aad8f0b40d23",
|
||||
"schema_version_31": "9290ef295731b03ddfe32dcaded0be70d41b63572420ad379cf2874a9b54581c",
|
||||
"schema_version_32": "5b4de8dd2d7e3c6ae4150e0e3931df2ee989f2c667145bd67294e5a5f3fae456",
|
||||
"schema_version_33": "bf38514efeb6c12511f41b1cc484f92722240b0a6ae874c32a958dfea3433d02",
|
||||
"schema_version_4": "216ea3a7d3e1704e40c797b5dc47456517c27dbb6ca98bf88812f4f63d74b5d9",
|
||||
"schema_version_5": "46397e2f5f2c82116786127e9f6a403e975b14d2ca7b652a48cd1ba843e6a27c",
|
||||
"schema_version_6": "9d05b4fb223f0e60efc716add5048b0ca9c37511cf2041721e20505d6d798ce4",
|
||||
|
|
1
database/sql/schema_version_33.sql
Normal file
1
database/sql/schema_version_33.sql
Normal file
|
@ -0,0 +1 @@
|
|||
alter table users add column show_reading_time boolean default 't';
|
|
@ -82,6 +82,10 @@ var translations = map[string]string{
|
|||
"entry.unshare.label": "Nicht teilen",
|
||||
"entry.shared_entry.title": "Öffnen Sie den öffentlichen Link",
|
||||
"entry.shared_entry.label": "Teilen",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d Minute gelesen",
|
||||
"%d Minuten gelesen"
|
||||
],
|
||||
"page.shared_entries.title": "Geteilte Artikel",
|
||||
"page.unread.title": "Ungelesen",
|
||||
"page.starred.title": "Lesezeichen",
|
||||
|
@ -264,6 +268,7 @@ var translations = map[string]string{
|
|||
"form.prefs.select.older_first": "Älteste Artikel zuerst",
|
||||
"form.prefs.select.recent_first": "Neueste Artikel zuerst",
|
||||
"form.prefs.label.keyboard_shortcuts": "Tastaturkürzel aktivieren",
|
||||
"form.prefs.label.show_reading_time": "Geschätzte Lesezeit für Artikel anzeigen",
|
||||
"form.prefs.label.custom_css": "Benutzerdefiniertes CSS",
|
||||
"form.import.label.file": "OPML Datei",
|
||||
"form.import.label.url": "URL",
|
||||
|
@ -422,6 +427,10 @@ var translations = map[string]string{
|
|||
"entry.unshare.label": "Unshare",
|
||||
"entry.shared_entry.title": "Open the public link",
|
||||
"entry.shared_entry.label": "Share",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minute read",
|
||||
"%d minutes read"
|
||||
],
|
||||
"page.shared_entries.title": "Shared Entries",
|
||||
"page.unread.title": "Unread",
|
||||
"page.starred.title": "Starred",
|
||||
|
@ -604,6 +613,7 @@ var translations = map[string]string{
|
|||
"form.prefs.select.older_first": "Older entries first",
|
||||
"form.prefs.select.recent_first": "Recent entries first",
|
||||
"form.prefs.label.keyboard_shortcuts": "Enable keyboard shortcuts",
|
||||
"form.prefs.label.show_reading_time": "Show estimated reading time for articles",
|
||||
"form.prefs.label.custom_css": "Custom CSS",
|
||||
"form.import.label.file": "OPML file",
|
||||
"form.import.label.url": "URL",
|
||||
|
@ -742,6 +752,10 @@ var translations = map[string]string{
|
|||
"entry.unshare.label": "No compartir",
|
||||
"entry.shared_entry.title": "Abrir el enlace público",
|
||||
"entry.shared_entry.label": "Compartir",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minuto de lectura",
|
||||
"%d minutos de lectura"
|
||||
],
|
||||
"page.shared_entries.title": "Entradas compartidas",
|
||||
"page.unread.title": "No leídos",
|
||||
"page.starred.title": "Marcadores",
|
||||
|
@ -924,6 +938,7 @@ var translations = map[string]string{
|
|||
"form.prefs.select.older_first": "Entradas más viejas primero",
|
||||
"form.prefs.select.recent_first": "Entradas recientes primero",
|
||||
"form.prefs.label.keyboard_shortcuts": "Habilitar atajos de teclado",
|
||||
"form.prefs.label.show_reading_time": "Mostrar el tiempo estimado de lectura de los artículos",
|
||||
"form.prefs.label.custom_css": "CSS personalizado",
|
||||
"form.import.label.file": "Archivo OPML",
|
||||
"form.import.label.url": "URL",
|
||||
|
@ -1062,6 +1077,10 @@ var translations = map[string]string{
|
|||
"entry.unshare.label": "Enlever le partage",
|
||||
"entry.shared_entry.title": "Ouvrir le lien public",
|
||||
"entry.shared_entry.label": "Partage",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minute de lecture",
|
||||
"%d minutes de lecture"
|
||||
],
|
||||
"page.shared_entries.title": "Articles partagés",
|
||||
"page.unread.title": "Non lus",
|
||||
"page.starred.title": "Favoris",
|
||||
|
@ -1244,6 +1263,7 @@ var translations = map[string]string{
|
|||
"form.prefs.select.older_first": "Ancien éléments en premier",
|
||||
"form.prefs.select.recent_first": "Éléments récents en premier",
|
||||
"form.prefs.label.keyboard_shortcuts": "Activer les raccourcis clavier",
|
||||
"form.prefs.label.show_reading_time": "Afficher le temps de lecture estimé des articles",
|
||||
"form.prefs.label.custom_css": "CSS personnalisé",
|
||||
"form.import.label.file": "Fichier OPML",
|
||||
"form.import.label.url": "URL",
|
||||
|
@ -1402,6 +1422,10 @@ var translations = map[string]string{
|
|||
"entry.unshare.label": "Unshare",
|
||||
"entry.shared_entry.title": "Apri il link pubblico",
|
||||
"entry.shared_entry.label": "Condivisione",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minuto di lettura",
|
||||
"%d minuti di lettura"
|
||||
],
|
||||
"page.shared_entries.title": "Voci condivise",
|
||||
"page.unread.title": "Da leggere",
|
||||
"page.starred.title": "Preferiti",
|
||||
|
@ -1584,6 +1608,7 @@ var translations = map[string]string{
|
|||
"form.prefs.select.older_first": "Prima i più vecchi",
|
||||
"form.prefs.select.recent_first": "Prima i più recenti",
|
||||
"form.prefs.label.keyboard_shortcuts": "Abilita le scorciatoie da tastiera",
|
||||
"form.prefs.label.show_reading_time": "Mostra il tempo di lettura stimato per gli articoli",
|
||||
"form.prefs.label.custom_css": "CSS personalizzati",
|
||||
"form.import.label.file": "File OPML",
|
||||
"form.import.label.url": "URL",
|
||||
|
@ -1722,6 +1747,10 @@ var translations = map[string]string{
|
|||
"entry.unshare.label": "共有解除",
|
||||
"entry.shared_entry.title": "公開リンクを開く",
|
||||
"entry.shared_entry.label": "共有する",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d分で読む",
|
||||
"%d分で読む"
|
||||
],
|
||||
"page.shared_entries.title": "共有エントリ",
|
||||
"page.unread.title": "未読",
|
||||
"page.starred.title": "星付き",
|
||||
|
@ -1904,6 +1933,7 @@ var translations = map[string]string{
|
|||
"form.prefs.select.older_first": "古い記事を最初に",
|
||||
"form.prefs.select.recent_first": "新しい記事を最初に",
|
||||
"form.prefs.label.keyboard_shortcuts": "キーボード・ショートカットを有効にする",
|
||||
"form.prefs.label.show_reading_time": "記事の推定読書時間を表示する",
|
||||
"form.prefs.label.custom_css": "カスタムCSS",
|
||||
"form.import.label.file": "OPML ファイル",
|
||||
"form.import.label.url": "URL",
|
||||
|
@ -2042,6 +2072,10 @@ var translations = map[string]string{
|
|||
"entry.unshare.label": "Delen ongedaan maken",
|
||||
"entry.shared_entry.title": "Open de openbare link",
|
||||
"entry.shared_entry.label": "Delen",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minuut gelezen",
|
||||
"%d minuten gelezen"
|
||||
],
|
||||
"page.shared_entries.title": "Gedeelde vermeldingen",
|
||||
"page.unread.title": "Ongelezen",
|
||||
"page.starred.title": "Favorieten",
|
||||
|
@ -2224,6 +2258,7 @@ var translations = map[string]string{
|
|||
"form.prefs.select.older_first": "Oudere items eerst",
|
||||
"form.prefs.select.recent_first": "Recente items eerst",
|
||||
"form.prefs.label.keyboard_shortcuts": "Schakel sneltoetsen in",
|
||||
"form.prefs.label.show_reading_time": "Toon geschatte leestijd voor artikelen",
|
||||
"form.prefs.label.custom_css": "Aangepaste CSS",
|
||||
"form.import.label.file": "OPML-bestand",
|
||||
"form.import.label.url": "URL",
|
||||
|
@ -2380,6 +2415,10 @@ var translations = map[string]string{
|
|||
"entry.unshare.label": "Unshare",
|
||||
"entry.shared_entry.title": "Otwórz publiczny link",
|
||||
"entry.shared_entry.label": "Udostępnianie",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minuta czytania",
|
||||
"%d minut czytania"
|
||||
],
|
||||
"page.shared_entries.title": "Udostępnione wpisy",
|
||||
"page.unread.title": "Nieprzeczytane",
|
||||
"page.starred.title": "Oznaczone gwiazdką",
|
||||
|
@ -2563,6 +2602,7 @@ var translations = map[string]string{
|
|||
"form.prefs.label.entries_per_page": "Wpisy na stronie",
|
||||
"form.prefs.select.older_first": "Najstarsze wpisy jako pierwsze",
|
||||
"form.prefs.label.keyboard_shortcuts": "Włącz skróty klawiaturowe",
|
||||
"form.prefs.label.show_reading_time": "Pokaż szacowany czas czytania artykułów",
|
||||
"form.prefs.select.recent_first": "Najnowsze wpisy jako pierwsze",
|
||||
"form.prefs.label.custom_css": "Niestandardowy CSS",
|
||||
"form.import.label.file": "Plik OPML",
|
||||
|
@ -2726,6 +2766,10 @@ var translations = map[string]string{
|
|||
"entry.unshare.label": "Descompartilhar",
|
||||
"entry.shared_entry.title": "Abrir link público",
|
||||
"entry.shared_entry.label": "Compartilhar",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minuto lido",
|
||||
"%d minutos lidos"
|
||||
],
|
||||
"page.shared_entries.title": "Itens compartilhados",
|
||||
"page.unread.title": "Não lídos",
|
||||
"page.starred.title": "Favoritos",
|
||||
|
@ -2908,6 +2952,7 @@ var translations = map[string]string{
|
|||
"form.prefs.select.older_first": "Itens mais velhos primeiro",
|
||||
"form.prefs.select.recent_first": "Itens mais recentes",
|
||||
"form.prefs.label.keyboard_shortcuts": "Habilitar atalhos do teclado",
|
||||
"form.prefs.label.show_reading_time": "Mostrar tempo estimado de leitura de artigos",
|
||||
"form.prefs.label.custom_css": "CSS customizado",
|
||||
"form.import.label.file": "Arquivo OPML",
|
||||
"form.import.label.url": "URL",
|
||||
|
@ -3046,6 +3091,10 @@ var translations = map[string]string{
|
|||
"entry.unshare.label": "Удалить из общедоступных",
|
||||
"entry.shared_entry.title": "Открыть публичную ссылку",
|
||||
"entry.shared_entry.label": "Поделиться",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d минута чтения",
|
||||
"%d минут чтения"
|
||||
],
|
||||
"page.shared_entries.title": "Общедоступные записи",
|
||||
"page.unread.title": "Непрочитанное",
|
||||
"page.starred.title": "Избранное",
|
||||
|
@ -3230,6 +3279,7 @@ var translations = map[string]string{
|
|||
"form.prefs.select.older_first": "Сначала старые записи",
|
||||
"form.prefs.select.recent_first": "Сначала последние записи",
|
||||
"form.prefs.label.keyboard_shortcuts": "Включить сочетания клавиш",
|
||||
"form.prefs.label.show_reading_time": "Показать примерное время чтения статей",
|
||||
"form.prefs.label.custom_css": "Пользовательские CSS",
|
||||
"form.import.label.file": "OPML файл",
|
||||
"form.import.label.url": "URL",
|
||||
|
@ -3374,6 +3424,10 @@ var translations = map[string]string{
|
|||
"entry.unshare.label": "取消分享",
|
||||
"entry.shared_entry.title": "打开公共链接",
|
||||
"entry.shared_entry.label": "分享分享",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d分钟阅读",
|
||||
"%d分钟阅读"
|
||||
],
|
||||
"page.shared_entries.title": "共享条目",
|
||||
"page.unread.title": "未读",
|
||||
"page.starred.title": "星标",
|
||||
|
@ -3554,6 +3608,7 @@ var translations = map[string]string{
|
|||
"form.prefs.select.older_first": "旧->新",
|
||||
"form.prefs.select.recent_first": "新->旧",
|
||||
"form.prefs.label.keyboard_shortcuts": "启用键盘快捷键",
|
||||
"form.prefs.label.show_reading_time": "显示文章的预计阅读时间",
|
||||
"form.prefs.label.custom_css": "自定义CSS",
|
||||
"form.import.label.file": "OPML 文件",
|
||||
"form.import.label.url": "URL",
|
||||
|
@ -3629,15 +3684,15 @@ var translations = map[string]string{
|
|||
}
|
||||
|
||||
var translationsChecksums = map[string]string{
|
||||
"de_DE": "e986a40b1748968725ddede18ae6451e4d1ae270b9c4c033daa81ee50b1d306e",
|
||||
"en_US": "b27169fc7767e51e6f7610ff1844708e8111e527c7931e3f888864a66826e293",
|
||||
"es_ES": "20a713468ca6ce00e899a80354912e927ded61cf8a79ad9d976c78f515e242dd",
|
||||
"fr_FR": "251eb14fe8521bde772d293fa748307ecd4cae4b0597da03aad39e745a382f11",
|
||||
"it_IT": "8ab664ec8d826aa3702a4f5294c3a3e87193437e64b0ef4990a3a9609b782786",
|
||||
"ja_JP": "7dc146dc5815a8d6dbae2f7f467deea598a85099bbee63e92bf3862d445519af",
|
||||
"nl_NL": "fd106f08b2f8902712a68716a0e33b063bdce32a8440f7a2b296b4f822088403",
|
||||
"pl_PL": "85de665d29e873f6099ef5ea40efe569a05ec3cbf08e4ca7741778bf3d5c8593",
|
||||
"pt_BR": "193847c5691590926e684894ef971141f69c0e2aaf270457e10331d75a29e34b",
|
||||
"ru_RU": "6e765e44e250469fe1c5666f8ff24e5e07e6b04098c1325c2663a1f722e0bfe9",
|
||||
"zh_CN": "0dc8c5b86a03f0ce58f6d2633ab3011d9bc8004af18f922944a65d151e54beda",
|
||||
"de_DE": "f3dd20afc5cbd9ac689bec2939c1d2fbe71372360c4e8f335e3b8cbce4228958",
|
||||
"en_US": "30cbcb2170782f1e66f69066947bf053f68065d7b270eea879f2c573819dd52b",
|
||||
"es_ES": "50dc7c8c2db7368bae133f5b455721470d314321153d41e4f27436a0f3f176e6",
|
||||
"fr_FR": "373fd2db868961758bd1483c34f117b03aadea17080f268bc8bbd0acdfbc5eed",
|
||||
"it_IT": "8d8f0bd75b4e7dec9370647c888dd9438b691130d9c41f839cdfff8cbc606cb5",
|
||||
"ja_JP": "ec3a21c547e4625ad359624e43ba31b556fb8d8b8ff7fc7a20df089317db99b3",
|
||||
"nl_NL": "20e180be2375f07ec02eb05f372a9102c13037a79e5651ce9bd41507fd2180d2",
|
||||
"pl_PL": "b1526955641823708b4c1ca753b61e1e0561d0a3d33da3f62170540903031b0d",
|
||||
"pt_BR": "cf8e131d39daac82d3157c6538c0643392a06358b7bc98be8579412ebd63f60e",
|
||||
"ru_RU": "4056e4e94861835d44064273371adbbded7190e2b719769886eb99e6c9feaf82",
|
||||
"zh_CN": "044abb0a34eee3d8d5597811d40166762311b8e4cd08b891796113790cc775f0",
|
||||
}
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
"entry.unshare.label": "Nicht teilen",
|
||||
"entry.shared_entry.title": "Öffnen Sie den öffentlichen Link",
|
||||
"entry.shared_entry.label": "Teilen",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d Minute gelesen",
|
||||
"%d Minuten gelesen"
|
||||
],
|
||||
"page.shared_entries.title": "Geteilte Artikel",
|
||||
"page.unread.title": "Ungelesen",
|
||||
"page.starred.title": "Lesezeichen",
|
||||
|
@ -259,6 +263,7 @@
|
|||
"form.prefs.select.older_first": "Älteste Artikel zuerst",
|
||||
"form.prefs.select.recent_first": "Neueste Artikel zuerst",
|
||||
"form.prefs.label.keyboard_shortcuts": "Tastaturkürzel aktivieren",
|
||||
"form.prefs.label.show_reading_time": "Geschätzte Lesezeit für Artikel anzeigen",
|
||||
"form.prefs.label.custom_css": "Benutzerdefiniertes CSS",
|
||||
"form.import.label.file": "OPML Datei",
|
||||
"form.import.label.url": "URL",
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
"entry.unshare.label": "Unshare",
|
||||
"entry.shared_entry.title": "Open the public link",
|
||||
"entry.shared_entry.label": "Share",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minute read",
|
||||
"%d minutes read"
|
||||
],
|
||||
"page.shared_entries.title": "Shared Entries",
|
||||
"page.unread.title": "Unread",
|
||||
"page.starred.title": "Starred",
|
||||
|
@ -259,6 +263,7 @@
|
|||
"form.prefs.select.older_first": "Older entries first",
|
||||
"form.prefs.select.recent_first": "Recent entries first",
|
||||
"form.prefs.label.keyboard_shortcuts": "Enable keyboard shortcuts",
|
||||
"form.prefs.label.show_reading_time": "Show estimated reading time for articles",
|
||||
"form.prefs.label.custom_css": "Custom CSS",
|
||||
"form.import.label.file": "OPML file",
|
||||
"form.import.label.url": "URL",
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
"entry.unshare.label": "No compartir",
|
||||
"entry.shared_entry.title": "Abrir el enlace público",
|
||||
"entry.shared_entry.label": "Compartir",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minuto de lectura",
|
||||
"%d minutos de lectura"
|
||||
],
|
||||
"page.shared_entries.title": "Entradas compartidas",
|
||||
"page.unread.title": "No leídos",
|
||||
"page.starred.title": "Marcadores",
|
||||
|
@ -259,6 +263,7 @@
|
|||
"form.prefs.select.older_first": "Entradas más viejas primero",
|
||||
"form.prefs.select.recent_first": "Entradas recientes primero",
|
||||
"form.prefs.label.keyboard_shortcuts": "Habilitar atajos de teclado",
|
||||
"form.prefs.label.show_reading_time": "Mostrar el tiempo estimado de lectura de los artículos",
|
||||
"form.prefs.label.custom_css": "CSS personalizado",
|
||||
"form.import.label.file": "Archivo OPML",
|
||||
"form.import.label.url": "URL",
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
"entry.unshare.label": "Enlever le partage",
|
||||
"entry.shared_entry.title": "Ouvrir le lien public",
|
||||
"entry.shared_entry.label": "Partage",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minute de lecture",
|
||||
"%d minutes de lecture"
|
||||
],
|
||||
"page.shared_entries.title": "Articles partagés",
|
||||
"page.unread.title": "Non lus",
|
||||
"page.starred.title": "Favoris",
|
||||
|
@ -259,6 +263,7 @@
|
|||
"form.prefs.select.older_first": "Ancien éléments en premier",
|
||||
"form.prefs.select.recent_first": "Éléments récents en premier",
|
||||
"form.prefs.label.keyboard_shortcuts": "Activer les raccourcis clavier",
|
||||
"form.prefs.label.show_reading_time": "Afficher le temps de lecture estimé des articles",
|
||||
"form.prefs.label.custom_css": "CSS personnalisé",
|
||||
"form.import.label.file": "Fichier OPML",
|
||||
"form.import.label.url": "URL",
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
"entry.unshare.label": "Unshare",
|
||||
"entry.shared_entry.title": "Apri il link pubblico",
|
||||
"entry.shared_entry.label": "Condivisione",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minuto di lettura",
|
||||
"%d minuti di lettura"
|
||||
],
|
||||
"page.shared_entries.title": "Voci condivise",
|
||||
"page.unread.title": "Da leggere",
|
||||
"page.starred.title": "Preferiti",
|
||||
|
@ -259,6 +263,7 @@
|
|||
"form.prefs.select.older_first": "Prima i più vecchi",
|
||||
"form.prefs.select.recent_first": "Prima i più recenti",
|
||||
"form.prefs.label.keyboard_shortcuts": "Abilita le scorciatoie da tastiera",
|
||||
"form.prefs.label.show_reading_time": "Mostra il tempo di lettura stimato per gli articoli",
|
||||
"form.prefs.label.custom_css": "CSS personalizzati",
|
||||
"form.import.label.file": "File OPML",
|
||||
"form.import.label.url": "URL",
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
"entry.unshare.label": "共有解除",
|
||||
"entry.shared_entry.title": "公開リンクを開く",
|
||||
"entry.shared_entry.label": "共有する",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d分で読む",
|
||||
"%d分で読む"
|
||||
],
|
||||
"page.shared_entries.title": "共有エントリ",
|
||||
"page.unread.title": "未読",
|
||||
"page.starred.title": "星付き",
|
||||
|
@ -259,6 +263,7 @@
|
|||
"form.prefs.select.older_first": "古い記事を最初に",
|
||||
"form.prefs.select.recent_first": "新しい記事を最初に",
|
||||
"form.prefs.label.keyboard_shortcuts": "キーボード・ショートカットを有効にする",
|
||||
"form.prefs.label.show_reading_time": "記事の推定読書時間を表示する",
|
||||
"form.prefs.label.custom_css": "カスタムCSS",
|
||||
"form.import.label.file": "OPML ファイル",
|
||||
"form.import.label.url": "URL",
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
"entry.unshare.label": "Delen ongedaan maken",
|
||||
"entry.shared_entry.title": "Open de openbare link",
|
||||
"entry.shared_entry.label": "Delen",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minuut gelezen",
|
||||
"%d minuten gelezen"
|
||||
],
|
||||
"page.shared_entries.title": "Gedeelde vermeldingen",
|
||||
"page.unread.title": "Ongelezen",
|
||||
"page.starred.title": "Favorieten",
|
||||
|
@ -259,6 +263,7 @@
|
|||
"form.prefs.select.older_first": "Oudere items eerst",
|
||||
"form.prefs.select.recent_first": "Recente items eerst",
|
||||
"form.prefs.label.keyboard_shortcuts": "Schakel sneltoetsen in",
|
||||
"form.prefs.label.show_reading_time": "Toon geschatte leestijd voor artikelen",
|
||||
"form.prefs.label.custom_css": "Aangepaste CSS",
|
||||
"form.import.label.file": "OPML-bestand",
|
||||
"form.import.label.url": "URL",
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
"entry.unshare.label": "Unshare",
|
||||
"entry.shared_entry.title": "Otwórz publiczny link",
|
||||
"entry.shared_entry.label": "Udostępnianie",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minuta czytania",
|
||||
"%d minut czytania"
|
||||
],
|
||||
"page.shared_entries.title": "Udostępnione wpisy",
|
||||
"page.unread.title": "Nieprzeczytane",
|
||||
"page.starred.title": "Oznaczone gwiazdką",
|
||||
|
@ -260,6 +264,7 @@
|
|||
"form.prefs.label.entries_per_page": "Wpisy na stronie",
|
||||
"form.prefs.select.older_first": "Najstarsze wpisy jako pierwsze",
|
||||
"form.prefs.label.keyboard_shortcuts": "Włącz skróty klawiaturowe",
|
||||
"form.prefs.label.show_reading_time": "Pokaż szacowany czas czytania artykułów",
|
||||
"form.prefs.select.recent_first": "Najnowsze wpisy jako pierwsze",
|
||||
"form.prefs.label.custom_css": "Niestandardowy CSS",
|
||||
"form.import.label.file": "Plik OPML",
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
"entry.unshare.label": "Descompartilhar",
|
||||
"entry.shared_entry.title": "Abrir link público",
|
||||
"entry.shared_entry.label": "Compartilhar",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d minuto lido",
|
||||
"%d minutos lidos"
|
||||
],
|
||||
"page.shared_entries.title": "Itens compartilhados",
|
||||
"page.unread.title": "Não lídos",
|
||||
"page.starred.title": "Favoritos",
|
||||
|
@ -259,6 +263,7 @@
|
|||
"form.prefs.select.older_first": "Itens mais velhos primeiro",
|
||||
"form.prefs.select.recent_first": "Itens mais recentes",
|
||||
"form.prefs.label.keyboard_shortcuts": "Habilitar atalhos do teclado",
|
||||
"form.prefs.label.show_reading_time": "Mostrar tempo estimado de leitura de artigos",
|
||||
"form.prefs.label.custom_css": "CSS customizado",
|
||||
"form.import.label.file": "Arquivo OPML",
|
||||
"form.import.label.url": "URL",
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
"entry.unshare.label": "Удалить из общедоступных",
|
||||
"entry.shared_entry.title": "Открыть публичную ссылку",
|
||||
"entry.shared_entry.label": "Поделиться",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d минута чтения",
|
||||
"%d минут чтения"
|
||||
],
|
||||
"page.shared_entries.title": "Общедоступные записи",
|
||||
"page.unread.title": "Непрочитанное",
|
||||
"page.starred.title": "Избранное",
|
||||
|
@ -261,6 +265,7 @@
|
|||
"form.prefs.select.older_first": "Сначала старые записи",
|
||||
"form.prefs.select.recent_first": "Сначала последние записи",
|
||||
"form.prefs.label.keyboard_shortcuts": "Включить сочетания клавиш",
|
||||
"form.prefs.label.show_reading_time": "Показать примерное время чтения статей",
|
||||
"form.prefs.label.custom_css": "Пользовательские CSS",
|
||||
"form.import.label.file": "OPML файл",
|
||||
"form.import.label.url": "URL",
|
||||
|
|
|
@ -77,6 +77,10 @@
|
|||
"entry.unshare.label": "取消分享",
|
||||
"entry.shared_entry.title": "打开公共链接",
|
||||
"entry.shared_entry.label": "分享分享",
|
||||
"entry.estimated_reading_time": [
|
||||
"%d分钟阅读",
|
||||
"%d分钟阅读"
|
||||
],
|
||||
"page.shared_entries.title": "共享条目",
|
||||
"page.unread.title": "未读",
|
||||
"page.starred.title": "星标",
|
||||
|
@ -257,6 +261,7 @@
|
|||
"form.prefs.select.older_first": "旧->新",
|
||||
"form.prefs.select.recent_first": "新->旧",
|
||||
"form.prefs.label.keyboard_shortcuts": "启用键盘快捷键",
|
||||
"form.prefs.label.show_reading_time": "显示文章的预计阅读时间",
|
||||
"form.prefs.label.custom_css": "自定义CSS",
|
||||
"form.import.label.file": "OPML 文件",
|
||||
"form.import.label.url": "URL",
|
||||
|
|
|
@ -23,6 +23,7 @@ type User struct {
|
|||
EntryDirection string `json:"entry_sorting_direction"`
|
||||
EntriesPerPage int `json:"entries_per_page"`
|
||||
KeyboardShortcuts bool `json:"keyboard_shortcuts"`
|
||||
ShowReadingTime bool `json:"show_reading_time"`
|
||||
LastLoginAt *time.Time `json:"last_login_at,omitempty"`
|
||||
Extra map[string]string `json:"extra"`
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ func (s *Storage) CreateUser(user *model.User) (err error) {
|
|||
VALUES
|
||||
(LOWER($1), $2, $3, $4)
|
||||
RETURNING
|
||||
id, username, is_admin, language, theme, timezone, entry_direction, entries_per_page, keyboard_shortcuts
|
||||
id, username, is_admin, language, theme, timezone, entry_direction, entries_per_page, keyboard_shortcuts, show_reading_time
|
||||
`
|
||||
|
||||
err = s.db.QueryRow(query, user.Username, password, user.IsAdmin, extra).Scan(
|
||||
|
@ -77,6 +77,7 @@ func (s *Storage) CreateUser(user *model.User) (err error) {
|
|||
&user.EntryDirection,
|
||||
&user.EntriesPerPage,
|
||||
&user.KeyboardShortcuts,
|
||||
&user.ShowReadingTime,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf(`store: unable to create user: %v`, err)
|
||||
|
@ -125,9 +126,10 @@ func (s *Storage) UpdateUser(user *model.User) error {
|
|||
timezone=$6,
|
||||
entry_direction=$7,
|
||||
entries_per_page=$8,
|
||||
keyboard_shortcuts=$9
|
||||
keyboard_shortcuts=$9,
|
||||
show_reading_time=$10
|
||||
WHERE
|
||||
id=$10
|
||||
id=$11
|
||||
`
|
||||
|
||||
_, err = s.db.Exec(
|
||||
|
@ -141,6 +143,7 @@ func (s *Storage) UpdateUser(user *model.User) error {
|
|||
user.EntryDirection,
|
||||
user.EntriesPerPage,
|
||||
user.KeyboardShortcuts,
|
||||
user.ShowReadingTime,
|
||||
user.ID,
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -156,9 +159,10 @@ func (s *Storage) UpdateUser(user *model.User) error {
|
|||
timezone=$5,
|
||||
entry_direction=$6,
|
||||
entries_per_page=$7,
|
||||
keyboard_shortcuts=$8
|
||||
keyboard_shortcuts=$8,
|
||||
show_reading_time=$9
|
||||
WHERE
|
||||
id=$9
|
||||
id=$10
|
||||
`
|
||||
|
||||
_, err := s.db.Exec(
|
||||
|
@ -171,6 +175,7 @@ func (s *Storage) UpdateUser(user *model.User) error {
|
|||
user.EntryDirection,
|
||||
user.EntriesPerPage,
|
||||
user.KeyboardShortcuts,
|
||||
user.ShowReadingTime,
|
||||
user.ID,
|
||||
)
|
||||
|
||||
|
@ -209,6 +214,7 @@ func (s *Storage) UserByID(userID int64) (*model.User, error) {
|
|||
entry_direction,
|
||||
entries_per_page,
|
||||
keyboard_shortcuts,
|
||||
show_reading_time,
|
||||
last_login_at,
|
||||
extra
|
||||
FROM
|
||||
|
@ -232,6 +238,7 @@ func (s *Storage) UserByUsername(username string) (*model.User, error) {
|
|||
entry_direction,
|
||||
entries_per_page,
|
||||
keyboard_shortcuts,
|
||||
show_reading_time,
|
||||
last_login_at,
|
||||
extra
|
||||
FROM
|
||||
|
@ -255,6 +262,7 @@ func (s *Storage) UserByExtraField(field, value string) (*model.User, error) {
|
|||
entry_direction,
|
||||
entries_per_page,
|
||||
keyboard_shortcuts,
|
||||
show_reading_time,
|
||||
last_login_at,
|
||||
extra
|
||||
FROM
|
||||
|
@ -278,6 +286,7 @@ func (s *Storage) UserByAPIKey(token string) (*model.User, error) {
|
|||
u.entry_direction,
|
||||
u.entries_per_page,
|
||||
u.keyboard_shortcuts,
|
||||
u.show_reading_time,
|
||||
u.last_login_at,
|
||||
u.extra
|
||||
FROM
|
||||
|
@ -304,6 +313,7 @@ func (s *Storage) fetchUser(query string, args ...interface{}) (*model.User, err
|
|||
&user.EntryDirection,
|
||||
&user.EntriesPerPage,
|
||||
&user.KeyboardShortcuts,
|
||||
&user.ShowReadingTime,
|
||||
&user.LastLoginAt,
|
||||
&extra,
|
||||
)
|
||||
|
@ -360,6 +370,7 @@ func (s *Storage) Users() (model.Users, error) {
|
|||
entry_direction,
|
||||
entries_per_page,
|
||||
keyboard_shortcuts,
|
||||
show_reading_time,
|
||||
last_login_at,
|
||||
extra
|
||||
FROM
|
||||
|
@ -386,6 +397,7 @@ func (s *Storage) Users() (model.Users, error) {
|
|||
&user.EntryDirection,
|
||||
&user.EntriesPerPage,
|
||||
&user.KeyboardShortcuts,
|
||||
&user.ShowReadingTime,
|
||||
&user.LastLoginAt,
|
||||
&extra,
|
||||
)
|
||||
|
|
|
@ -237,6 +237,13 @@ SOFTWARE.
|
|||
<li>
|
||||
<time datetime="{{ isodate .entry.Date }}" title="{{ isodate .entry.Date }}">{{ elapsed .user.Timezone .entry.Date }}</time>
|
||||
</li>
|
||||
{{ if .user.ShowReadingTime }}
|
||||
<li>
|
||||
<span>
|
||||
{{ plural "entry.estimated_reading_time" (timeToRead .entry.Content) (timeToRead .entry.Content) }}
|
||||
</span>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
<ul class="item-meta-icons">
|
||||
{{ if .entry.ShareCode }}
|
||||
|
@ -510,7 +517,7 @@ var templateCommonMapChecksums = map[string]string{
|
|||
"feed_list": "30acc9ecc413811e73a1dad120b5d44e29564de3ba794fb07ee886b30addfb19",
|
||||
"feed_menu": "318d8662dda5ca9dfc75b909c8461e79c86fb5082df1428f67aaf856f19f4b50",
|
||||
"icons": "3dbe754a98f524a227111191d76b8c6944711b13613cc548ee9e9808fe0bffb4",
|
||||
"item_meta": "a5b07cc6597e5c8f3ca849ee486acb3f16f062d8a1eaa47d2fb402ae6825b7ef",
|
||||
"item_meta": "a5b686c7af6348fdbd9a147e3fcfacc4a0b442c3b9637f3dce026ccf367fc312",
|
||||
"layout": "91d2ab3f683a2ced5e9ce5cd04919e74b3e3f329a5eedcc60015b8d49ecb1b77",
|
||||
"pagination": "7b61288e86283c4cf0dc83bcbf8bf1c00c7cb29e60201c8c0b633b2450d2911f",
|
||||
"settings_menu": "e2b777630c0efdbc529800303c01d6744ed3af80ec505ac5a5b3f99c9b989156",
|
||||
|
|
|
@ -65,6 +65,9 @@ func (e *Engine) Render(name, language string, data interface{}) []byte {
|
|||
"plural": func(key string, n int, args ...interface{}) string {
|
||||
return printer.Plural(key, n, args...)
|
||||
},
|
||||
"timeToRead": func(content string) int {
|
||||
return timeToRead(content)
|
||||
},
|
||||
})
|
||||
|
||||
var b bytes.Buffer
|
||||
|
|
|
@ -92,6 +92,9 @@ func (f *funcMap) Map() template.FuncMap {
|
|||
"plural": func(key string, n int, args ...interface{}) string {
|
||||
return ""
|
||||
},
|
||||
"timeToRead": func(content string) int {
|
||||
return 0
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,3 +221,9 @@ func formatFileSize(b int64) string {
|
|||
return fmt.Sprintf("%.1f %ciB",
|
||||
float64(b)/float64(div), "KMGTPE"[exp])
|
||||
}
|
||||
|
||||
func timeToRead(content string) int {
|
||||
nbOfWords := len(strings.Fields(content))
|
||||
|
||||
return int(math.Ceil(float64(nbOfWords) / 265))
|
||||
}
|
||||
|
|
|
@ -7,6 +7,13 @@
|
|||
<li>
|
||||
<time datetime="{{ isodate .entry.Date }}" title="{{ isodate .entry.Date }}">{{ elapsed .user.Timezone .entry.Date }}</time>
|
||||
</li>
|
||||
{{ if .user.ShowReadingTime }}
|
||||
<li>
|
||||
<span>
|
||||
{{ plural "entry.estimated_reading_time" (timeToRead .entry.Content) (timeToRead .entry.Content) }}
|
||||
</span>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
<ul class="item-meta-icons">
|
||||
{{ if .entry.ShareCode }}
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
|
||||
<label><input type="checkbox" name="keyboard_shortcuts" value="1" {{ if .form.KeyboardShortcuts }}checked{{ end }}> {{ t "form.prefs.label.keyboard_shortcuts" }}</label>
|
||||
|
||||
<label><input type="checkbox" name="show_reading_time" value="1" {{ if .form.ShowReadingTime }}checked{{ end }}> {{ t "form.prefs.label.show_reading_time" }}</label>
|
||||
|
||||
<label>{{t "form.prefs.label.custom_css" }}</label><textarea name="custom_css" cols="40" rows="5">{{ .form.CustomCSS }}</textarea>
|
||||
<div class="buttons">
|
||||
<button type="submit" class="button button-primary" data-label-loading="{{ t "form.submit.saving" }}">{{ t "action.update" }}</button>
|
||||
|
|
|
@ -1325,6 +1325,8 @@ var templateViewsMap = map[string]string{
|
|||
|
||||
<label><input type="checkbox" name="keyboard_shortcuts" value="1" {{ if .form.KeyboardShortcuts }}checked{{ end }}> {{ t "form.prefs.label.keyboard_shortcuts" }}</label>
|
||||
|
||||
<label><input type="checkbox" name="show_reading_time" value="1" {{ if .form.ShowReadingTime }}checked{{ end }}> {{ t "form.prefs.label.show_reading_time" }}</label>
|
||||
|
||||
<label>{{t "form.prefs.label.custom_css" }}</label><textarea name="custom_css" cols="40" rows="5">{{ .form.CustomCSS }}</textarea>
|
||||
<div class="buttons">
|
||||
<button type="submit" class="button button-primary" data-label-loading="{{ t "form.submit.saving" }}">{{ t "action.update" }}</button>
|
||||
|
@ -1568,7 +1570,7 @@ var templateViewsMapChecksums = map[string]string{
|
|||
"login": "79ff2ca488c0a19b37c8fa227a21f73e94472eb357a51a077197c852f7713f11",
|
||||
"search_entries": "c0786ddc6b17e865007b975eefb97417935cbc601f5917cca1ee0d3f584594bc",
|
||||
"sessions": "5d5c677bddbd027e0b0c9f7a0dd95b66d9d95b4e130959f31fb955b926c2201c",
|
||||
"settings": "3d6dd0d7fa0ca48cfd9a5edb43c055af8b816eb4460f16b71ae22db40ed9b754",
|
||||
"settings": "a4d3df17e6abc75881ec1ca5f92a9c2cfe24e3e08e5d844df848b4d6aaa1bbc0",
|
||||
"shared_entries": "1494d81e46f6af534a73cf6a91f8dfda1932a477bb3a70143513896ac0f0220b",
|
||||
"unread_entries": "e0080d0cf3583cda51d865422960137c8556c432853657086e43daf6bd5b73be",
|
||||
"users": "d7ff52efc582bbad10504f4a04fa3adcc12d15890e45dff51cac281e0c446e45",
|
||||
|
|
|
@ -23,6 +23,7 @@ type SettingsForm struct {
|
|||
EntryDirection string
|
||||
EntriesPerPage int
|
||||
KeyboardShortcuts bool
|
||||
ShowReadingTime bool
|
||||
CustomCSS string
|
||||
}
|
||||
|
||||
|
@ -35,6 +36,7 @@ func (s *SettingsForm) Merge(user *model.User) *model.User {
|
|||
user.EntryDirection = s.EntryDirection
|
||||
user.EntriesPerPage = s.EntriesPerPage
|
||||
user.KeyboardShortcuts = s.KeyboardShortcuts
|
||||
user.ShowReadingTime = s.ShowReadingTime
|
||||
user.Extra["custom_css"] = s.CustomCSS
|
||||
|
||||
if s.Password != "" {
|
||||
|
@ -88,6 +90,7 @@ func NewSettingsForm(r *http.Request) *SettingsForm {
|
|||
EntryDirection: r.FormValue("entry_direction"),
|
||||
EntriesPerPage: int(entriesPerPage),
|
||||
KeyboardShortcuts: r.FormValue("keyboard_shortcuts") == "1",
|
||||
ShowReadingTime: r.FormValue("show_reading_time") == "1",
|
||||
CustomCSS: r.FormValue("custom_css"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ func (h *handler) showSettingsPage(w http.ResponseWriter, r *http.Request) {
|
|||
EntryDirection: user.EntryDirection,
|
||||
EntriesPerPage: user.EntriesPerPage,
|
||||
KeyboardShortcuts: user.KeyboardShortcuts,
|
||||
ShowReadingTime: user.ShowReadingTime,
|
||||
CustomCSS: user.Extra["custom_css"],
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue