From b621be06dfaddea07c1be02358ca7516a7bffa82 Mon Sep 17 00:00:00 2001
From: Artyom <33123862+NikkoFox@users.noreply.github.com>
Date: Sat, 14 Mar 2026 17:50:36 +0300
Subject: [PATCH 1/4] Improve Russian translation (#503)
* Translate to ru and fix arrays
* Update translate strings to ru
* Update made_for_you
---
app/src/main/res/values-ru/arrays.xml | 115 +++--
app/src/main/res/values-ru/strings.xml | 599 ++++++++++++++++---------
2 files changed, 466 insertions(+), 248 deletions(-)
diff --git a/app/src/main/res/values-ru/arrays.xml b/app/src/main/res/values-ru/arrays.xml
index 0c2e6ace..860c31c5 100644
--- a/app/src/main/res/values-ru/arrays.xml
+++ b/app/src/main/res/values-ru/arrays.xml
@@ -1,19 +1,19 @@
- - Светлый
- - Темный
- - Системный по умолчанию
+ - Светлая
+ - Темная
+ - Системная по умолчанию
- - светлый
- - темный
- - по умолчанию
+ - light
+ - dark
+ - default
- - Высокий
+ - Большой
- Средний
- - Низкий
+ - Маленький
- 500
@@ -22,9 +22,9 @@
- - Высокий
- - Средний
- - Низкий
+ - Высокое
+ - Среднее
+ - Низкое
- -1
@@ -165,7 +165,7 @@
- - Прямая загрузка
+ - Оригинал
- Opus
- AAC
- Mp3
@@ -191,9 +191,9 @@
- - Высокий
- - Средний
- - Низкий
+ - Сильное скругление
+ - Среднее скругление
+ - Небольшое скругление
- 18
@@ -202,23 +202,23 @@
- - Отключенный
+ - Выключено
- Трек
- Альбом
- Авто
- - отключенный
- - трек
- - альбом
- - авто
+ - disabled
+ - track
+ - album
+ - auto
- - Не перекодировать
+ - Не транскодировать
- Настройки сервера
- Формат транскодирования Wi-Fi
- - Формат мобильного транскодирования
+ - Формат транскодирования моб. сети
- 0
@@ -229,9 +229,9 @@
- Минимум
- - Умеренный
- - Агрессивный
- - Экстремальный
+ - Умеренно
+ - Агрессивно
+ - Экстремально
- .1
@@ -240,6 +240,15 @@
- 8
+
+ - По названию
+ - Случайно
+
+
+ - ORDER_BY_NAME
+ - ORDER_BY_RANDOM
+
+
- 0 звезд минимум
- 1 звезда минимум
@@ -254,4 +263,60 @@
- 3
- 4
+
+ - 3"
+ - 4
+ - 5
+ - 6
+ - 7
+
+
+ - 3
+ - 4
+ - 5
+ - 6
+ - 7
+
+
+
+
+ - Не показывать
+ - Главная
+ - Недавние
+ - Альбомы
+ - Артисты
+ - Плейлисты
+ - Подкасты
+ - Радио
+ - Папки
+ - Популярные альбомы
+
+ - Недавно добавленные альбомы
+
+ - Избранные треки
+ - Избранные альбомы
+ - Избранные артисты
+ - Случайное
+
+
+ - -1
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+ - 7
+ - 8
+ - 9
+ - 10
+ - 11
+ - 12
+ - 13
+ - 14
+ - 15
+
+
+
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 5df9b304..9315a180 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -1,161 +1,204 @@
- Если у вас возникли проблемы, посетите https://dontkillmyapp.com. Он содержит подробные инструкции о том, как отключить любые функции энергосбережения, которые могут повлиять на производительность приложения.
+ Альбомы
+ Популярные альбомы
+ Добавленные альбомы
+ Артисты
+ Главная
+ Персональная подборка
+ Еще
+ Папка
+ Плейлисты
+ Подкасты
+ Радио
+ Случайное
+ Недавние
+ Недавно воспроизведенные
+ ★ Альбомы
+ ★ Артисты
+ ★ Треки
+
+ Если возникают проблемы, посетите https://dontkillmyapp.com. Сайт содержит инструкции по отключению функций энергосбережения, которые могут влиять на работу приложения.
Пожалуйста, отключите оптимизацию батареи для воспроизведения мультимедиа при выключенном экране.
Оптимизация батареи
- Автономный режим
+ Офлайн-режим
Добавить в плейлист
Добавить в очередь
Скачать все
Перейти к исполнителю
Мгновенный микс
- Играть дальше
+ Играть следующим
Убрать все
Поделиться
Перемешать
Альбомы
- Просмотр альбомов
- Не удалось получить исполнителя.
+ Обзор альбомов
+ Не удалось получить исполнителя
Скачанные альбомы
Самые проигрываемые альбомы
Новые релизы
Недавно добавленные альбомы
Недавно воспроизведенные альбомы
- Помеченные альбомы
+ Избранные альбомы
Альбомы
Больше подобного
Играть
- Выпущен %1$s
- Выпущен %1$s, оригинал %2$s
- Смешать
- %1$d треков • %2$d минут
+ Дата релиза: %1$s
+ Дата релиза: %1$s, оригинал %2$s
+ Перемешать
+ %1$d треков • %2$d минут(ы)
Tempus
Поиск…
Мгновенный микс
- Смешать
- Артисты
- Просмотр исполнителя
- Ошибка при получении радио исполнителя.
- Ошибка при получении треков исполнителя.
+ Перемешать
+ Исполнители
+ Обзор исполнителей
+ Ошибка при получении радио исполнителя
+ Ошибка при получении треков исполнителя
Скачанные исполнители
- Рейтинговые исполнители
+ Избранные исполнители
Исполнители
+ Нет данных об исполнителе
Радио
Смешать
- Переключить раскладку
+ Сменить вид
Больше подобного
Альбомы
Больше
Биография
- Самые прослушиваемые треки
- Посмотреть все
+ Самые популярные треки
+ Все
Игнорировать
Больше не спрашивать
Отключить
+ Создания мгновенного микса...
+ Не удалось получить треки с сервера Subsonic.
Отмена
- Включить сохранение данных
+ Включить экономию данных
OK
- Доступ к серверу Subsonic по соединениям, отличным от Wi-Fi, ограничен. Чтобы это диалоговое окно предупреждения не появлялось снова, отключите проверку соединения в настройках приложения.
+ Доступ к серверу Subsonic по соединениям, отличным от Wi-Fi, ограничен. Чтобы это окно больше не появлялось, отключите проверку соединения в настройках приложения.
Wi-Fi не подключен
Перемешать
Отмена
Продолжить
- Имейте в виду, что продолжение этого действия приведет к безвозвратному удалению всех сохраненных элементов, загруженных со всех серверов.
+ Обратите внимание, что продолжение приведёт к безвозвратному удалению всех сохранённых элементов, загруженных со всех серверов.
Удалить сохраненные элементы
- Нет описания
+ Текст песни недоступен
Диск %1$s - %2$s
Диск %1$s
Отмена
- Загрузить
- Все треки из этой папки будут загружены. Треки, находящиеся в подпапках, не будут загружены.
+ Скачать
+ Все треки из этой папки будут скачаны. Треки в подпапках скачаны не будут.
Скачать треки
- Скачав песню, вы найдете ее здесь.
+ Выбрать место скачанной музыки
+ Скачав песню, вы найдете ее здесь
Загрузок пока нет!
- %1$s • %2$s товаров
- %1$s предметов
+ %1$s • %2$s элементов
+ %1$s элементов
Перемешать все
Чтобы изменения вступили в силу, перезапустите приложение.
- Изменение места назначения загружаемых файлов из одного хранилища в другое приведет к немедленному удалению всех ранее загруженных файлов в другом хранилище.
- Выберите вариант хранения
- Внешний
- Внутренний
+ Изменение места хранения загрузок приведёт к немедленному удалению ранее скачанных файлов из старого хранилища.
+ Выберите хранилище
+ Внешнее
+ Внутреннее
+ Директория
Загрузки
+ Укажите директорию загрузок, чтобы обновить список.
+ Отсутствующие загрузки не найдены.
+
+ - Удалена %d отсутствующая загрузка.
+ - Удалено %d отсутствующих загрузок.
+
+ Обновить список загрузок
Добавить в очередь
- Играть дальше
+ Играть следующим
Удалить
- Убрать все
- Смешать
-
- Необходимый
+ Удалить все
+ Перемешать
+
+ Обязательно
Требуется префикс http или https
Загрузки
+ Убрать лайк
+ Поставить лайк
+ Загрузка…
Выберите два или более фильтров
Фильтр
Фильтровать исполнителей
- Фильтровать жанры
+ Фильтровать по жанрам
+ (%1$d)
+ (+%1$d)
Каталог жанров
- Просмотр жанров
+ Обзор жанров
Напомнить позже
Поддержать меня
Скачать сейчас
На Github доступна новая версия приложения.
Доступно обновление
Отмена
- Перезагрузить
- Сохранять
+ Сброс
+ Сохранить
Настроить главную
- Обратите внимание, чтобы внесенные изменения вступили в силу, необходимо перезапустить приложение.
+ Чтобы внесенные изменения вступили в силу, необходимо перезапустить приложение.
Музыка
Подкасты
Радио
Лучшие треки любимых исполнителей
- Запустите микс с понравившимся вам треком
+ Начните микс с понравившегося трека
Добавить новое радио
Добавить новый канал подкаста
Отмена
Скачать
- Загрузка этих треков может потребовать значительного использования данных
- Похоже, есть несколько отмеченных треков для синхронизации.
- Синхронизировать отмеченные альбомы
- Отмеченные альбомы будут доступны в автономном режиме
+ Загрузка этих треков может потребовать значительный объем трафика
+ Похоже, есть любимые треки для синхронизации
+ Синхронизиция любимых альбомов
+ Любимые альбомы будут доступны офлайн
+ Синхронизиция любимых артистов
+ У вас есть любимые артисты, музыка которых не скачана
+
+ - %d трек требует синхронизации
+ - %d треков требуют синхронизации
+
Лучшее из
Открытие
Перемешать все
Воспоминание
Интернет-радиостанции
- Последнее воспроизведение
- Увидеть все
- На прошлой неделе
+ Недавно воспроизведенные
+ Все
+ Прошлая неделя
Прошлый месяц
Прошлый год
- Сделано для тебя
- Самое популярное
- Увидеть все
+ Персональная подборка
+ Популярные
+ Все
Новые релизы
- Новейшие подкасты
+ Новые подкасты
Плейлисты
Каналы
- Увидеть все
+ Все
Радиостанции
- Недавно добавленный
- Увидеть все
+ Недавно добавленные
+ Все
Общий доступ
- ★ Отмеченные альбомы
- Увидеть все
- ★ Рейтинговые артисты
- Увидеть все
- ★ Отмеченные треки
- Увидеть все
+ ★ Любимые альбомы
+ Все
+ ★ Любимые исполнители
+ Все
+ ★ Любимые треки
+ Все
Ваши лучшие треки
- Реорганизовать
+ Настроить
+ •
+ --
Альбомы
- Увидеть все
+ Все
Исполнители
- Увидеть все
+ Все
Жанры
- Увидеть все
- Музыкальные папки
+ Все
+ Папки с музыкой
Плейлисты
- Увидеть все
+ Все
Сервер не добавлен
Subsonic серверы
Subsonic серверы
@@ -164,7 +207,7 @@
Добавить в плейлист
Скачать все
Оценить альбом
- Скачать
+ Скачанное
Все
Загружено
Альбом
@@ -180,58 +223,75 @@
Поиск
Настройки
Исполнитель
- Имя
- Случайный
- Недавно добавленный
- Недавно воспроизведенный
- Самое популярное
- Недавно отмеченный
- Давно отмеченный
+ Название
+ Случайно
+ Количество альбомов
+ Недавно добавленные
+ Недавно воспроизведенные
+ Популярные
+ Недавно понравившиеся
+ Давно понравившиеся
Год
Добавить на главный экран
Убрать с главного экрана
%1$.2fx
- Очистить очередь воспроизведения
+ Скорость воспроизведения
+ Отмена
+ Очистить очередь
Очередь сохранена
+ Сохранить очередь в плейлист
+ Загрузить очередь
+ Скачать текст песни для офлайн-прослушивания
+ Текст песни сохранён для офлайн-прослушивания
+ Текст песни сохранён для офлайн-прослушивания.
+ Текст песни недоступен для скачивания.
Приоритет сервера
- Неизвестный форма
- Транскодирование
+ Неизвестный формат
+ Транскодирвание
запрошено
Каталог плейлистов
- Просмотр плейлистов
+ Обзор плейлистов
Плейлисты не созданы
Отмена
Создать
Добавить в плейлист
- Добавьте песню в плейлист
- Не удалось добавить песню в список воспроизведения
+ Трек(и) добавлены в плейлист
+ Не удалось добавить трек(и) в плейлист
+ Трек удалён из плейлиста
+ Не удалось удалить трек из плейлиста
+ Все треки пропущены как дубликаты
+ Публичный
+ Приватный
+ Сделать плейлист публичным
+ Сервер обновляет видимость при каждом запросе. По умолчанию плейлист приватный.
%1$d треков • %2$s
- Продолжительность • %1$s
- Долгое нажатие для удаления
+ Длительность • %1$s
+ Удерживайте для удаления
Название плейлиста
Отмена
Удалить
- Сохранять
+ Сохранить
Редактировать плейлист
Воспроизвести
- Смешать
- Плейлист • %1$d треки
+ Перемешать
+ Плейлист • %1$d треков
Добавить в очередь
Удалить
Скачать
- Перейти на канал
- Играть дальше
+ Перейти к каналу
+ Играть следующим
Удалить
Каналы
- Просмотр каналов
+ Обзор каналов
RSS-адрес
- Подкаст-канал
+ Канал подкаста
+ Подкасты не поддерживаются этим сервером.
Описание
Эпизоды
- Нет доступных серий
+ Эпизоды отсутствуют
Ваш запрос отправлен на сервер
- Нажмите, чтобы скрыть раздел. Изменения будут видны при перезапуске
- Добавив канал, вы найдете его здесь
+ Нажмите, чтобы скрыть раздел\nИзменения вступят в силу после перезапуска
+ После добавления канала он появится здесь
Подкасты не найдены!
%1$s • %2$s
URL-адрес домашней страницы радио
@@ -239,215 +299,308 @@
URL-адрес радиопотока
Отмена
Удалить
- Сохранять
+ Сохранить
+ Радиостанция добавлена
+ Радиостанция обновлена
Интернет-радиостанция
- Нажмите, чтобы скрыть раздел. Изменения будут видны при перезапуске
- Добавив радиостанцию, вы найдете ее здесь
+ Нажмите, чтобы скрыть раздел\nИзменения вступят в силу после перезапуска
+ После добавления радиостанции она появится здесь
Станции не найдены!
+ Управление интернет-радио не поддерживается этим сервером.
Отмена
- Сохранять
+ Сохранить
Рейтинг
- Поиск по названию, исполнителям или альбомам
+ Поиск по названию, артистам или альбомам
Введите не менее трех символов
Альбомы
Исполнители
Треки
Низкая безопасность
- Долгое нажатие для удаления
+ Удерживайте для удаления
Локальный URL
- Имя сервера
+ Название сервера
Пароль
URL-адрес сервера
Имя пользователя
+ Клиентский сертификат (необязательно)
Отмена
Удалить
Сохранить
Добавить сервер
Отмена
- Перейти к входу
+ Перейти ко входу
Продолжить в любом случае
- Запрошенный сервер недоступен. Если вы решите продолжить, это диалоговое окно не появится в течение следующего часа
+ Запрошенный сервер недоступен. Если вы продолжите, это сообщение не появится в течение следующего часа.
Сервер недоступен
- Tempus — это легкий музыкальный клиент с открытым исходным кодом для Subsonic, разработанный и созданный специально для Android.
- О нас
- Показать детали альбома
- Если включено, отображать информацию об альбоме, например жанр, количество песен и т. д., на странице альбома.
- Разрешить добавление дубликатов в плейлист
- Если включено, дубликаты не будут проверяться при добавлении в плейлист..
- Всегда на дисплее
- Сортировать исполнителей по количеству альбомов
- Если включено, сортировать исполнителей по количеству альбомов. Если отключено, сортировать по имени.
- Формат перекодирования
- Если этот параметр включен, Tempus не будет принудительно загружать трек с настройками перекодирования, указанными ниже.
- Установите приоритет настроек сервера, используемых для потоковой передачи при загрузке
- Если этот параметр включен, Tempus будет загружать перекодированные треки.
- Скачать перекодированные треки
- Если этот параметр включен, на сервере будет запрошена предполагаемая продолжительность трека.
- Оцените длину содержимого
- Формат перекодирования для загрузки
- Формат перекодирования в мобильном телефоне
- Перекодировать формат в Wi-Fi
- Если этот параметр включен, Tempus не будет принудительно транслировать трек с настройками перекодирования, указанными ниже.
- Приоритизация настроек перекодирования сервера
- Приоритет при перекодировании трека отдается серверу
+ Tempus — это легкий музыкальный клиент с открытым исходным кодом для Subsonic, разработанный специально под Android.
+ О приложении
+ Always On Display
+ Разрешить дубликаты в плейлистах
+ Если включено, дубликаты не будут проверяться при добавлении в плейлист.
+ Формат транскодирования
+ Если включено, Tempus не будет принудительно скачивать трек с настройками транскодирования, указанными ниже.
+ Использовать серверные настройки транскодирования при скачивании
+ Если включено, Tempus будет скачивать треки в транскодированном виде.
+ Скачивать транскодированные треки
+ Если включено, на сервере будет запрошена предполагаемая продолжительность трека.
+ Оценить длительность трека
+ Формат при скачивании
+ Формат транскод. в моб. сети 4G/5G
+ Формат транскод. в сети Wi-Fi
+ Если включено, Tempus не будет принудительно стримить трек с настройками транскодирования, указанными ниже.
+ Приоритет серверных настроек транскодирования
+ Приоритет транскодирования передан серверу
Стратегия буферизации
- Чтобы изменения вступили в силу, необходимо вручную перезапустить приложение.
- Разрешить играть включать треки после окончания плейлиста
- Продолжать играть
- Размер кэша обложек
- Чтобы сократить потребление данных, избегайте загрузки обложек.
- Ограничить использование мобильных данных
- Продолжение приведет к необратимому удалению всех сохраненных элементов.
- Удалить сохраненные элементы
- Загрузить хранилище
- Отрегулируйте настройки звука
+ Чтобы изменения вступили в силу, необходимо перезапустить приложение.
+ Выберите папку для загруженной музыки
+ Сбросить папку загрузок
+ Позволяет продолжать воспроизведение после окончания плейлиста
+ Непрерывное воспроизведение
+ Кэш обложек
+ Чтобы снизить расход трафика, обложки не будут загружаться.
+ Экономия мобильного трафика
+ Продолжение приведёт к безвозвратному удалению всех сохранённых элементов.
+ Удалить сохранённые элементы
+ Место хранения загрузок
+ Папка для загрузок сброшена
+ Папка для загрузок установлена
+ Выбрать папку для загрузок
+ Настройки звука
Системный эквалайзер
https://github.com/eddyizm/tempus
Следите за развитием
Github
- Установить разрешение изображения
+ https://github.com/eddyizm/tempus/discussions
+ Обновления
+ Проверять обновления на GitHub
+ Если используется версия из GitHub, приложение по умолчанию проверяет наличие новых APK-релизов. Отключите, чтобы запретить автоматическую проверку
+ Присоединяйтесь к обсуждениям в сообществе и оказывайте поддержку
+ Поддержка пользователей
+ Сканирование: найдено %1$d треков
+ Разрешение изображений
Язык
Выйти
- Битрейт для скачиваний
+ Тайм-аут подключения к серверу
+ Установите тайм-аут для локального URL. По умолчанию 2 секунды. (Для удалённого сервера значение x3, максимум 10 секунд.)
+ Установите базовый тайм-аут в секундах
+ Битрейт при скачивании
Битрейт в мобильной сети 4G/5G
- Битрейт через соединение Wi-Fi
+ Битрейт в сети Wi-Fi
Размер кэша медиафайлов
- Показать музыкальные каталоги
- Если включено, то показывать раздел музыкального каталога. Обратите внимание: для правильной работы навигации по папкам сервер должен поддерживать эту функцию.
- Показать подкаст
- Если включено, показывать раздел подкаста. Перезапустите приложение, чтобы оно вступило в силу.
- Показать качество звука (битрейт)
- Битрейт и аудиоформат будут показаны для каждой аудиодорожки.
- Показать рейтинг трека
- Если эта функция включена, будет отображаться пятизвездочный рейтинг трека на странице воспроизведения\n\n*Требует перезапуска приложения
- Показать рейтинг
- Если эта функция включена, будет отображаться рейтинг элемента и то, отмечен ли он как избранный.
+ Показывать музыкальные каталоги
+ Если включено, отображается раздел музыкальных каталогов. Для корректной навигации сервер должен поддерживать эту функцию.
+ Показывать подкасты
+ Если включено, отображается раздел подкастов. Перезапустите приложение, чтобы изменение вступило в силу.
+ Сортировка плейлистов
+ Android Auto
+ Grid view for albums
+ Grid view for home
+ Grid view for playlists
+ Grid view for podcast
+ Grid view for radio
+ First tab display
+ Second tab display
+ Third tab display
+ Fourth tab display
+ Показывать качество аудио
+ Битрейт и формат аудио будут отображаться для каждого трека.
+ Показывать рейтинг трека
+ Если включено, на странице воспроизведения будет отображаться пятизвёздочный рейтинг трека.\n\n*Требуется перезапуск приложения
+ Показывать рейтинг элементов
+ Если включено, отображается рейтинг элемента и отметка избранного.
Таймер синхронизации
- Если этот параметр включен, пользователь будет иметь возможность сохранять свою очередь воспроизведения и загружать состояние при открытии приложения.
- Синхронизировать очередь воспроизведения для этого пользователя
- Показать кнопку Shuffle
- Если включено, показывать кнопку перемешивания, убрать сердечко в мини-плеере
- Показать радио
- Если включено, показывать раздел радио. Перезапустите приложение, чтобы оно вступило в силу.
- Автоматическая загрузка текстов песен
- Автоматически сохранять тексты песен, когда они доступны, чтобы их можно было просматривать в автономном режиме.
- Установите режим усиления воспроизведения
- Закругленные углы
- Размер углов
- Устанавливает величину угла кривизны.
- Если этот параметр включен, задает угол кривизны для всех отображаемых обложек. Изменения вступят в силу при перезапуске.
+ Если включено, позволяет сохранять очередь воспроизведения и восстанавливать её при запуске приложения.
+ Синхронизация очереди воспроизведения [Экспериментально]
+ Показывать кнопку перемешивания
+ Если включено, в мини-плеере отображается кнопка перемешивания вместо сердечка.
+ Показывать радио
+ Если включено, отображается раздел радио. Перезапустите приложение, чтобы изменение вступило в силу.
+ Включить боковое меню в портретном режиме [Экспериментально]
+ Разблокирует боковое меню в портретной ориентации. Изменения вступят в силу после перезапуска.
+ Скрывать нижнюю панель в портретном режиме [Экспериментально]
+ Увеличивает вертикальное пространство, убирая нижнюю панель. Изменения вступят в силу после перезапуска.
+ Автоматически скачивать тексты песен
+ Тексты будут автоматически сохраняться, чтобы их можно было просматривать офлайн.
+ Режим ReplayGain
+ Скругление углов
+ Степень скругления углов
+ Определяет степень скругления углов.
+ Если включено, обложки будут отображаться со скругленными углами. Изменения вступят в силу после перезапуска.
Сканировать библиотеку
Включить скробблинг музыки Last.FM и т.д.
Язык системы
Включить обмен музыкой
- Размер кэша стриминга
+ Кэш стриминга
Хранилище кэша стриминга
- Важно отметить, что скробблинг также зависит от того, настроен ли сервер для получения этих данных.
- При прослушивании радио исполнителя, мгновенном миксе или перемешивании всех, треки ниже определенного пользовательского рейтинга будут игнорироваться.
- Усиление воспроизведения — это функция, которая позволяет регулировать уровень громкости звуковых дорожек для обеспечения единообразного качества прослушивания. Этот параметр действует только в том случае, если трек содержит необходимые метаданные.
- Скробблинг — это функция, которая позволяет вашему устройству отправлять информацию о песнях, которые вы слушаете, на музыкальный сервер. Эта информация помогает создавать персональные рекомендации на основе ваших музыкальных предпочтений.
- Позволяет пользователю делиться музыкой по ссылке. Функциональность должна поддерживаться и включаться на стороне сервера и ограничивается отдельными треками, альбомами и плейлистами.
- Возвращает состояние очереди воспроизведения для этого пользователя. Сюда входят треки в очереди воспроизведения, воспроизводимый в данный момент трек и позиция внутри этого трека. Сервер должен поддерживать эту функцию.
- %1$s \nСейчас используется: %2$s MiB
- Приоритет отдается режиму перекодирования. Если установлено «Прямое воспроизведение», битрейт файла не изменится.
- Загрузите перекодированные медиафайлы. Если этот параметр включен, будет использоваться не конечная точка загрузки, а следующие настройки. Если для параметра «Формат перекодирования для загрузки» установлено значение «Прямая загрузка», битрейт файла не изменится.
- Когда файл перекодируется на лету, клиент обычно не показывает длину трека. Можно запросить у серверов, поддерживающих данную функцию, оценку длительности воспроизводимого трека, но время ответа может занять больше времени.
- Если этот параметр включен, помеченные альбомы будут загружены для использования в автономном режиме.
- Синхронизировать помеченные альбомы для использования в автономном режиме.
- Если этот параметр включен, помеченные треки будут загружены для использования в автономном режиме.
- Синхронизировать помеченные треки для использования в автономном режиме.
- Синхронизировать избранных исполнителей для использования офлайн
- Присоединяйтесь к обсуждениям в сообществе и оказывайте поддержку
- Поддержка пользователей
+ Важно отметить, что скробблинг зависит от того, настроен ли сервер для получения этих данных.
+ При прослушивании радио исполнителя, мгновенного микса или при перемешивании все треки с рейтингом ниже указанного будут пропускаться.
+ ReplayGain позволяет выровнять громкость аудиотреков для более комфортного прослушивания. Работает только если файл содержит соответствующие метаданные.
+ Скробблинг позволяет отправлять информацию о прослушанных треках на музыкальный сервер. Это помогает формировать персональные рекомендации на основе ваших музыкальных предпочтений.
+ Позволяет делиться музыкой по ссылке. Функция должна поддерживаться и включаться на стороне сервера и ограничивается отдельными треками, альбомами и плейлистами.
+ Возвращает состояние очереди воспроизведения пользователя: список треков, текущий трек и позицию воспроизведения. Сервер должен поддерживать эту функцию.\n*Работает не на всех серверах и устройствах.
+ %1$s \nСейчас используется: %2$s MiB
+ Определяет приоритет режима транскодирования. Если выбрано «Прямое воспроизведение», битрейт файла не изменяется.
+ Загружать транскодированные медиафайлы. Если включено, для скачивания треков будут использоваться настройки ниже.\n\nЕсли для «Формат при скачивании» выбрано «Загружать оригинал», битрейт файла не изменяется.
+ При транскодировании на лету клиент может не отображать длительность трека. Есть возможность запросить у серверов, поддерживающих данную функцию, приблизительную длительность, но ответ может занять больше времени.
+ Применяется ко всем спискам альбомов и исполнителей. По умолчанию: 4
+ Если включено, любимые исполнители будут скачиваться для офлайн-прослушивания.
+ Синхронизировать избранных артистов для офлайн-прослушивания
+ Если включено, любимые альбомы будут скачиваться для офлайн-прослушивания.
+ Синхронизировать избранные альбомы для офлайн-прослушивания
+ Если включено, любимые треки будут скачиваться для офлайн-прослушивания.
+ Синхронизировать избранные треки для офлайн-прослушивания
Тема
Данные
- Общий
+ Общие
+ Плейлисты
Рейтинг
- Усиление воспроизведения
- Скроббл
+ ReplayGain
+ Скробблинг
Игнорировать треки по рейтингу
Треки с рейтингом:
- Поделиться
- Синхронизации
+ Общий доступ
+ Синхронизация
Транскодирование
Скачивание с транскодированием
- UI (Пользовательский интерфейс)
- Перекодированная загрузка
+ Пользовательский интерфейс
+ Элементов в строке (альбомная ориентация)
+ Количество элементов в строке
+ Загрузка с транскодированием
+
Версия
- Запросить подтверждение пользователя перед потоковой передачей по мобильной сети.
- Оповещение о потоковой передаче только через Wi-Fi
+ Запрашивать подтверждение перед стримингом через мобильную сеть.
+ Предупреждение при стриминге без Wi-Fi
Копировать ссылку
Удалить общий доступ
Обновить общий доступ
Срок действия: %1$s
+ Никогда
Общий доступ не поддерживается или не включен
+ Ссылка Tempus
+ UID трека
+ UID альбома
+ UID артиста
+ UID плейлиста
+ UID жанра
+ UID года
+ UID объекта
+ Неподдерживаемая ссылка
+ Не удалось открыть трек
+ Не удалось открыть альбом
+ Не удалось открыть исполнителя
+ Не удалось открыть плейлист
+ %1$s • %2$s
+ Скопировано в буфер обмена: %1$s
+ Ссылка объекта: %1$s
Описание
Дата окончания срока
Отмена
- Сохранять
+ Сохранить
Поделиться
Добавить в плейлист
Добавить в очередь
Скачать
- Ошибка при получении альбома
- Не удалось получить исполнителя
- Перейти в альбом
- Перейти к исполнителю
+ Ошибка получения альбома
+ Ошибка получения исполнителя
+ Перейти к альбому
+ Перейти к артисту
Мгновенный микс
- Играть дальше
+ Играть следующим
Оценить
- Удалить
+ Удалить с устройства
+ Удалить из плейлиста
Поделиться
- Загружено
+ Скачанное
Самые популярные треки
Недавно добавленные треки
Недавно воспроизведенные треки
- Помеченные треки
- %1$s\'s Лучшие треки
+ Избранные треки
+ %1$s лучших треков
Год %1$d
%1$s • %2$s %3$s
Отмена
Продолжить
Продолжить и скачать
- Для скачивания рейтинговых треков может потребоваться большой объем данных.
- Синхронизировать отмеченные треки
- Для скачивания рейтинговых альбомов может потребоваться большой объем данных.
- Синхронизировать отмеченные альбомы
- Чтобы изменения вступили в силу необходимо перезапустить приложение.
- Изменение места сохранения кэшированных файлов с одного на другое может привести к удалению файлов в старом хранилище.
- Выберите способ сохранения
- Внешний
- Внутренний
+ Загрузка любимых треков может потребовать значительный объем трафика.
+ Синхронизация избранных треков
+ Загрузка любимых исполнителей может потребовать значительный объем трафика.
+ Синхронизация избранных артистов
+ Загрузка любимых альбомов может потребовать значительный объем трафика.
+ Синхронизация избранных альбомы
+ Чтобы изменения вступили в силу, перезапустите приложение.
+ Изменение места хранения кэшированных файлов может привести к удалению ранее сохранённых файлов в старом хранилище.
+ Выберите хранилище
+ Внешнее
+ Внутреннее
+
Альбом
Исполнитель
Разрядность
Битрейт
- Тип содержимого
+ Тип контента
OK
Информация о треке
Номер диска
- Продолжительность
+ Длина
Жанр
Путь
- Частота сэмплирования
+ Частота дискретизации
Размер
- Суффикс
- Файл был загружен с использованием API Subsonic. Кодек и битрейт файла остаются неизменными по сравнению с исходным файлом.
- Приложение запросит сервер перекодировать файл и изменить его битрейт. Запрошенный пользователем кодек: %1$s, с битрейтом %2$s. Любые потенциальные изменения кодека и битрейта файла в выбранном формате будут обрабатываться сервером, который может поддерживать или не поддерживать эту операцию.
- Приложение будет читать только исходный файл, предоставленный сервером. Приложение явно запросит у сервера неперекодированный файл с битрейтом исходного источника.
- Качество воспроизводимого файла остается на усмотрение сервера. Приложение не будет принудительно выбирать кодек и битрейт для любого потенциального перекодирования.
- Приложение запросит сервер изменить битрейт файла. Пользователь запросил битрейт %1$s, при этом кодек исходного файла останется прежним. Любые изменения битрейта файла в выбранном формате будут выполняться сервером, который может поддерживать или не поддерживать эту операцию.
- Приложение запросит сервер перекодировать файл. Запрошенный пользователем кодек — %1$s, а битрейт будет такой же, как у исходного файла. Потенциальное перекодирование файла в выбранный формат зависит от сервера, поскольку он может поддерживать или не поддерживать эту операцию.
+ Расширение
+ Файл был загружен через API Subsonic. Кодек и битрейт остаются такими же, как в исходном файле.
+ Приложение запросит у сервера транскодирование файла с изменением битрейта. Запрошенный кодек: %1$s, битрейт: %2$s. Возможность изменения кодека и битрейта зависит от сервера и может не поддерживаться.
+ Приложение воспроизводит оригинальный файл, предоставленный сервером. Серверу отправляется запрос на получение файла без транскодирования и с исходным битрейтом.
+ Качество воспроизводимого файла остается на усмотрение сервера. Приложение не будет принудительно выбирать кодек или битрейт при транскодировании.
+ Приложение запросит у сервера изменение битрейта файла. Запрошенный битрейт: %1$s, кодек файла останется прежним. Возможность изменения битрейта файла зависит от сервера, который может поддерживать или не поддерживать эту операцию.
+ Приложение запросит у сервера транскодирование файла. Запрошенный кодек: %1$s, битрейт файла останется прежним. Возможность транскодирования файла в выбранный формат зависит от сервера, который может поддерживать или не поддерживать эту операцию.
Заголовок
Номер трека
- Тип транскодированного контента
- Транскодированный суффикс
+ Станция
+ Тип транскод. файла
+ Расширение транскод. файла
Год
- Развернуть
- Особая благодарность — команде unDraw, без иллюстраций которой мы не смогли бы сделать это приложение красивее.
- https://undraw.co/
+
+ Особая благодарность команде unDraw за иллюстрации, которые помогли сделать приложение красивее
+
+ Tempus Widget
+ Ничего не воспроизводится
+ Открыть Tempus
+ 0:00
+ 0:00
+ Обложка альбома
+ Плей или пауза
+ Следующий трек
+ Предыдущий трек
+ Перемешивание
+ Изменить режим повтора
- Альбомов для синхронизации: %d
- Альбомов для синхронизации: %d
+
+ - Исполнителей для синхронизации: %d
+ - Исполнителей для синхронизации: %d
+
+
+ - Скачивание %d трека
+ - Скачивание %d треков
+
+ Эквалайзер
+ Сброс
+ Включить
+ Не поддерживается на этом устройстве
+ Эквалайзер
+ Открыть встроенный эквалайзер
+
+ Показывать информацию об альбоме
+ Если включено, на странице альбома отображаются дополнительные сведения: жанр, количество треков и т.д.
+ Сортировать артистов по количеству альбомов
+ Если включено, исполнители сортируются по количеству альбомов. Если отключено - по имени.
+
+ Сканирование папки…
+ Воспроизведение %d треков
+ В папке нет треков
+
+ Сортировать недавние поиски по времени
+ Если включено, поиски сортируются по времени. Если отключено - по имени.
From b6e75afe12e44e9454c491586a6979fee5435e52 Mon Sep 17 00:00:00 2001
From: MaFo-28
Date: Sat, 14 Mar 2026 16:04:47 +0100
Subject: [PATCH 2/4] feat: tile size manager (#440)
* Add TileSizeManager and improve dynamic tile sizing
* Improve scale labels
* Add protection against invalid tile size preferences
* Fix DiscoverSongAdapter & move TileSizeManager
---
.../tempo/ui/adapter/AlbumAdapter.java | 12 ++
.../tempo/ui/adapter/ArtistAdapter.java | 11 ++
.../ui/adapter/ArtistSimilarAdapter.java | 12 ++
.../tempo/ui/adapter/DiscoverSongAdapter.java | 15 ++
.../ui/fragment/AlbumCatalogueFragment.java | 13 +-
.../ui/fragment/ArtistCatalogueFragment.java | 11 +-
.../tempo/ui/fragment/ArtistPageFragment.java | 12 +-
.../ui/fragment/GenreCatalogueFragment.java | 11 +-
.../ui/fragment/HomeTabMusicFragment.java | 10 +-
.../tempo/util/Preferences.kt | 5 +
.../tempo/util/TileSizeManager.java | 174 ++++++++++++++++++
.../res/layout/fragment_home_tab_music.xml | 8 +-
app/src/main/res/layout/fragment_library.xml | 1 -
.../res/layout/item_home_discover_song.xml | 39 ++--
app/src/main/res/layout/item_home_year.xml | 8 +-
.../main/res/layout/item_library_genre.xml | 2 +-
app/src/main/res/values-fr/arrays.xml | 14 ++
app/src/main/res/values-fr/strings.xml | 2 +
app/src/main/res/values/arrays.xml | 14 ++
app/src/main/res/values/strings.xml | 1 +
app/src/main/res/xml/global_preferences.xml | 20 +-
21 files changed, 334 insertions(+), 61 deletions(-)
create mode 100644 app/src/main/java/com/cappielloantonio/tempo/util/TileSizeManager.java
diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/AlbumAdapter.java b/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/AlbumAdapter.java
index 498bf237..d6e41746 100644
--- a/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/AlbumAdapter.java
+++ b/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/AlbumAdapter.java
@@ -13,6 +13,7 @@ import com.cappielloantonio.tempo.interfaces.ClickCallback;
import com.cappielloantonio.tempo.subsonic.models.AlbumID3;
import com.cappielloantonio.tempo.util.Constants;
import com.cappielloantonio.tempo.util.MusicUtil;
+import com.cappielloantonio.tempo.util.TileSizeManager;
import java.util.Collections;
import java.util.List;
@@ -22,6 +23,8 @@ public class AlbumAdapter extends RecyclerView.Adapter
private List albums;
+ private int sizePx = 400;
+
public AlbumAdapter(ClickCallback click) {
this.click = click;
this.albums = Collections.emptyList();
@@ -31,11 +34,20 @@ public class AlbumAdapter extends RecyclerView.Adapter
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ItemLibraryAlbumBinding view = ItemLibraryAlbumBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
+
+ TileSizeManager.getInstance().calculateTileSize(parent.getContext());
+ sizePx = TileSizeManager.getInstance().getTileSizePx(parent.getContext());
+
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
+ ViewGroup.LayoutParams lp = holder.item.albumCoverImageView.getLayoutParams();
+ lp.width = sizePx;
+ lp.height = sizePx;
+ holder.item.albumCoverImageView.setLayoutParams(lp);
+
AlbumID3 album = albums.get(position);
holder.item.albumNameLabel.setText(album.getName());
diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/ArtistAdapter.java b/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/ArtistAdapter.java
index 44e8402c..29bd773f 100644
--- a/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/ArtistAdapter.java
+++ b/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/ArtistAdapter.java
@@ -14,6 +14,7 @@ import com.cappielloantonio.tempo.interfaces.ClickCallback;
import com.cappielloantonio.tempo.subsonic.models.ArtistID3;
import com.cappielloantonio.tempo.util.Constants;
import com.cappielloantonio.tempo.util.MusicUtil;
+import com.cappielloantonio.tempo.util.TileSizeManager;
import java.util.Collections;
import java.util.List;
@@ -24,6 +25,7 @@ public class ArtistAdapter extends RecyclerView.Adapter artists;
public ArtistAdapter(ClickCallback click, Boolean mix, Boolean bestOf) {
@@ -37,11 +39,20 @@ public class ArtistAdapter extends RecyclerView.Adapter artists;
+ private int sizePx = 400;
+
public ArtistSimilarAdapter(ClickCallback click) {
this.click = click;
this.artists = Collections.emptyList();
@@ -31,11 +34,20 @@ public class ArtistSimilarAdapter extends RecyclerView.Adapter songs;
+ private int widthPx = 800;
+ private int heightPx = 400;
+
public DiscoverSongAdapter(ClickCallback click) {
this.click = click;
this.songs = Collections.emptyList();
@@ -32,11 +37,21 @@ public class DiscoverSongAdapter extends RecyclerView.Adapter originalAlbums;
@@ -92,9 +93,9 @@ public class AlbumCatalogueFragment extends Fragment implements ClickCallback {
bind = FragmentAlbumCatalogueBinding.inflate(inflater, container, false);
View view = bind.getRoot();
- if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
- spanCount = Preferences.getLandscapeItemsPerRow();
- }
+ TileSizeManager.getInstance().calculateTileSize( requireContext() );
+ spanCount = TileSizeManager.getInstance().getTileSpanCount( requireContext() );
+ tileSpacing = TileSizeManager.getInstance().getTileSpacing( requireContext() );
initAppBar();
initAlbumCatalogueView();
@@ -140,7 +141,7 @@ public class AlbumCatalogueFragment extends Fragment implements ClickCallback {
@SuppressLint("ClickableViewAccessibility")
private void initAlbumCatalogueView() {
bind.albumCatalogueRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), spanCount));
- bind.albumCatalogueRecyclerView.addItemDecoration(new GridItemDecoration(spanCount, 20, false));
+ bind.albumCatalogueRecyclerView.addItemDecoration(new GridItemDecoration(spanCount, tileSpacing, false));
bind.albumCatalogueRecyclerView.setHasFixedSize(true);
albumAdapter = new AlbumCatalogueAdapter(this, true);
diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistCatalogueFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistCatalogueFragment.java
index 5a2aa1ee..0df3b432 100644
--- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistCatalogueFragment.java
+++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistCatalogueFragment.java
@@ -36,6 +36,7 @@ import com.cappielloantonio.tempo.ui.activity.MainActivity;
import com.cappielloantonio.tempo.ui.adapter.ArtistCatalogueAdapter;
import com.cappielloantonio.tempo.util.Constants;
import com.cappielloantonio.tempo.util.Preferences;
+import com.cappielloantonio.tempo.util.TileSizeManager;
import com.cappielloantonio.tempo.viewmodel.ArtistCatalogueViewModel;
import com.cappielloantonio.tempo.subsonic.models.ArtistID3;
@@ -51,7 +52,9 @@ public class ArtistCatalogueFragment extends Fragment implements ClickCallback {
private ArtistCatalogueViewModel artistCatalogueViewModel;
private ArtistCatalogueAdapter artistAdapter;
+
private int spanCount = 2;
+ private int tileSpacing = 20;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -68,9 +71,9 @@ public class ArtistCatalogueFragment extends Fragment implements ClickCallback {
bind = FragmentArtistCatalogueBinding.inflate(inflater, container, false);
View view = bind.getRoot();
- if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
- spanCount = Preferences.getLandscapeItemsPerRow();
- }
+ TileSizeManager.getInstance().calculateTileSize( requireContext() );
+ spanCount = TileSizeManager.getInstance().getTileSpanCount( requireContext() );
+ tileSpacing = TileSizeManager.getInstance().getTileSpacing( requireContext() );
initAppBar();
initArtistCatalogueView();
@@ -115,7 +118,7 @@ public class ArtistCatalogueFragment extends Fragment implements ClickCallback {
@SuppressLint("ClickableViewAccessibility")
private void initArtistCatalogueView() {
bind.artistCatalogueRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), spanCount));
- bind.artistCatalogueRecyclerView.addItemDecoration(new GridItemDecoration(spanCount, 20, false));
+ bind.artistCatalogueRecyclerView.addItemDecoration(new GridItemDecoration(spanCount, tileSpacing, false));
bind.artistCatalogueRecyclerView.setHasFixedSize(true);
artistAdapter = new ArtistCatalogueAdapter(this);
diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistPageFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistPageFragment.java
index e995d209..74e3a44e 100644
--- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistPageFragment.java
+++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistPageFragment.java
@@ -43,6 +43,7 @@ import com.cappielloantonio.tempo.ui.adapter.SongHorizontalAdapter;
import com.cappielloantonio.tempo.util.Constants;
import com.cappielloantonio.tempo.util.MusicUtil;
import com.cappielloantonio.tempo.util.Preferences;
+import com.cappielloantonio.tempo.util.TileSizeManager;
import com.cappielloantonio.tempo.viewmodel.ArtistPageViewModel;
import com.cappielloantonio.tempo.viewmodel.PlaybackViewModel;
import com.google.common.util.concurrent.ListenableFuture;
@@ -65,6 +66,7 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
private ListenableFuture mediaBrowserListenableFuture;
private int spanCount = 2;
+ private int tileSpacing = 20;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -75,9 +77,9 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
artistPageViewModel = new ViewModelProvider(requireActivity()).get(ArtistPageViewModel.class);
playbackViewModel = new ViewModelProvider(requireActivity()).get(PlaybackViewModel.class);
- if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
- spanCount = Preferences.getLandscapeItemsPerRow();
- }
+ TileSizeManager.getInstance().calculateTileSize( requireContext() );
+ spanCount = TileSizeManager.getInstance().getTileSpanCount( requireContext() );
+ tileSpacing = TileSizeManager.getInstance().getTileSpacing( requireContext() );
init(view);
initAppBar();
@@ -285,7 +287,7 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
private void initAlbumsView() {
bind.albumsRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), spanCount));
- bind.albumsRecyclerView.addItemDecoration(new GridItemDecoration(spanCount, 20, false));
+ bind.albumsRecyclerView.addItemDecoration(new GridItemDecoration(spanCount, tileSpacing, false));
bind.albumsRecyclerView.setHasFixedSize(true);
albumCatalogueAdapter = new AlbumCatalogueAdapter(this, false);
@@ -304,7 +306,7 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
private void initSimilarArtistsView() {
bind.similarArtistsRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), spanCount));
- bind.similarArtistsRecyclerView.addItemDecoration(new GridItemDecoration(spanCount, 20, false));
+ bind.similarArtistsRecyclerView.addItemDecoration(new GridItemDecoration(spanCount, tileSpacing, false));
bind.similarArtistsRecyclerView.setHasFixedSize(true);
artistCatalogueAdapter = new ArtistCatalogueAdapter(this);
diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/GenreCatalogueFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/GenreCatalogueFragment.java
index 52e8b825..f421878c 100644
--- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/GenreCatalogueFragment.java
+++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/GenreCatalogueFragment.java
@@ -34,6 +34,7 @@ import com.cappielloantonio.tempo.ui.activity.MainActivity;
import com.cappielloantonio.tempo.ui.adapter.GenreCatalogueAdapter;
import com.cappielloantonio.tempo.util.Constants;
import com.cappielloantonio.tempo.util.Preferences;
+import com.cappielloantonio.tempo.util.TileSizeManager;
import com.cappielloantonio.tempo.viewmodel.GenreCatalogueViewModel;
@OptIn(markerClass = UnstableApi.class)
@@ -43,7 +44,9 @@ public class GenreCatalogueFragment extends Fragment implements ClickCallback {
private GenreCatalogueViewModel genreCatalogueViewModel;
private GenreCatalogueAdapter genreCatalogueAdapter;
+
private int spanCount = 2;
+ private int tileSpacing = 20;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -59,9 +62,9 @@ public class GenreCatalogueFragment extends Fragment implements ClickCallback {
View view = bind.getRoot();
genreCatalogueViewModel = new ViewModelProvider(requireActivity()).get(GenreCatalogueViewModel.class);
- if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
- spanCount = Preferences.getLandscapeItemsPerRow();
- }
+ TileSizeManager.getInstance().calculateGenreSize( requireContext() );
+ spanCount = TileSizeManager.getInstance().getGenreSpanCount( requireContext() );
+ tileSpacing = TileSizeManager.getInstance().getGenreSpacing( requireContext() );
init();
initAppBar();
@@ -105,7 +108,7 @@ public class GenreCatalogueFragment extends Fragment implements ClickCallback {
@SuppressLint("ClickableViewAccessibility")
private void initGenreCatalogueView() {
bind.genreCatalogueRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), spanCount));
- bind.genreCatalogueRecyclerView.addItemDecoration(new GridItemDecoration(spanCount, 16, false));
+ bind.genreCatalogueRecyclerView.addItemDecoration(new GridItemDecoration(spanCount, tileSpacing, false));
bind.genreCatalogueRecyclerView.setHasFixedSize(true);
genreCatalogueAdapter = new GenreCatalogueAdapter(this);
diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/HomeTabMusicFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/HomeTabMusicFragment.java
index b2bc5ee3..e745cdf4 100644
--- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/HomeTabMusicFragment.java
+++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/HomeTabMusicFragment.java
@@ -64,6 +64,7 @@ import com.cappielloantonio.tempo.util.ExternalAudioWriter;
import com.cappielloantonio.tempo.util.MappingUtil;
import com.cappielloantonio.tempo.util.MusicUtil;
import com.cappielloantonio.tempo.util.Preferences;
+import com.cappielloantonio.tempo.util.TileSizeManager;
import com.cappielloantonio.tempo.util.UIUtil;
import com.cappielloantonio.tempo.viewmodel.HomeViewModel;
import com.cappielloantonio.tempo.viewmodel.PlaybackViewModel;
@@ -682,11 +683,12 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
private void initDiscoverSongSlideView() {
if (homeViewModel.checkHomeSectorVisibility(Constants.HOME_SECTOR_DISCOVERY)) return;
- bind.discoverSongViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
+ bind.discoverSongRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
+ bind.discoverSongRecyclerView.setHasFixedSize(true);
discoverSongAdapter = new DiscoverSongAdapter(this);
- bind.discoverSongViewPager.setAdapter(discoverSongAdapter);
- bind.discoverSongViewPager.setOffscreenPageLimit(1);
+ bind.discoverSongRecyclerView.setAdapter(discoverSongAdapter);
+
homeViewModel.getDiscoverSongSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> {
MusicUtil.ratingFilter(songs);
@@ -699,8 +701,6 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
discoverSongAdapter.setItems(songs);
}
});
-
- setSlideViewOffset(bind.discoverSongViewPager, 20, 16);
}
private void initSimilarSongView() {
diff --git a/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt b/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt
index 099a471d..9f40758c 100644
--- a/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt
+++ b/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt
@@ -92,6 +92,7 @@ object Preferences {
private const val ARTIST_DISPLAY_BIOGRAPHY= "artist_display_biography"
private const val NETWORK_PING_TIMEOUT = "network_ping_timeout_base"
+ private const val TILE_SIZE = "tile_size"
private const val AA_ALBUM_VIEW = "androidauto_album_view"
private const val AA_HOME_VIEW = "androidauto_home_view"
private const val AA_PLAYLIST_VIEW = "androidauto_playlist_view"
@@ -769,6 +770,10 @@ object Preferences {
}
@JvmStatic
+ fun getTileSize(): Int {
+ val parsed = App.getInstance().preferences.getString(TILE_SIZE, "2")?.toIntOrNull()
+ return parsed?.takeIf { it in 2..6 } ?: 2
+ }
fun isAndroidAutoAlbumViewEnabled(): Boolean {
return App.getInstance().preferences.getBoolean(AA_ALBUM_VIEW, true)
}
diff --git a/app/src/main/java/com/cappielloantonio/tempo/util/TileSizeManager.java b/app/src/main/java/com/cappielloantonio/tempo/util/TileSizeManager.java
new file mode 100644
index 00000000..a7ee7745
--- /dev/null
+++ b/app/src/main/java/com/cappielloantonio/tempo/util/TileSizeManager.java
@@ -0,0 +1,174 @@
+package com.cappielloantonio.tempo.util;
+
+import android.content.Context;
+import android.util.DisplayMetrics;
+
+public class TileSizeManager {
+
+ private static TileSizeManager instance;
+
+ private int tileSizePx;
+ private int tileSpanCount;
+ private int tileSpacing;
+ private int genreSizePx;
+ private int genreSpanCount;
+ private int genreSpacing;
+ private int GenreSpacing;
+ private int discoverWidthPx;
+ private int discoverHeightPx;
+ private boolean tileIsInitialized;
+ private boolean genreIsInitialized;
+ private boolean discoverIsInitialized;
+
+ private TileSizeManager() {
+ }
+
+ public static TileSizeManager getInstance() {
+ if (instance == null) {
+ instance = new TileSizeManager();
+ }
+ return instance;
+ }
+
+ public int getTileSizePx(Context context) {
+ if( !tileIsInitialized )
+ calculateTileSize(context);
+ return tileSizePx;
+ }
+ public int getTileSpanCount(Context context) {
+ if( !tileIsInitialized )
+ calculateTileSize(context);
+ return tileSpanCount;
+ }
+ public int getTileSpacing(Context context) {
+ if( !tileIsInitialized )
+ calculateTileSize(context);
+ return tileSpacing;
+ }
+ public int getGenreSizePx(Context context) {
+ if( !genreIsInitialized )
+ calculateGenreSize(context);
+ return genreSizePx;
+ }
+ public int getGenreSpanCount(Context context) {
+ if( !genreIsInitialized )
+ calculateGenreSize(context);
+ return genreSpanCount;
+ }
+ public int getGenreSpacing(Context context) {
+ if( !genreIsInitialized )
+ calculateGenreSize(context);
+ return genreSpacing;
+ }
+ public int getDiscoverWidthPx(Context context) {
+ if( !discoverIsInitialized )
+ calculateTileSize(context);
+ return discoverWidthPx;
+ }
+ public int getDiscoverHeightPx(Context context) {
+ if( !discoverIsInitialized )
+ calculateTileSize(context);
+ return discoverHeightPx;
+ }
+
+ public void calculateTileSize(Context context) {
+ DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ float screenWidth = metrics.widthPixels;
+ float screenHeight = metrics.heightPixels;
+
+ // retrieve the divisor in the preferences
+ int userTileSize = Math.max(2, Math.min(6, Preferences.getTileSize()));
+ float divisor = (float)userTileSize;
+
+ // little pading = 10
+ tileSizePx = Math.round(Math.min(screenWidth, screenHeight) / divisor) - 10;
+ tileSpanCount = Math.max(2, Math.round(screenWidth / (float)tileSizePx) );
+
+ switch (userTileSize) {
+ default:
+ case 2: // XL
+ tileSpacing = 20;
+ break;
+ case 3: // L
+ tileSpacing = 15;
+ break;
+ case 4: // M
+ tileSpacing = 10;
+ break;
+ case 5: // S
+ tileSpacing = 6;
+ break;
+ case 6: // SX
+ tileSpacing = 2;
+ break;
+ }
+ tileIsInitialized = true;
+ }
+
+ public void calculateGenreSize(Context context) {
+ DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ float screenWidth = metrics.widthPixels;
+ float screenHeight = metrics.heightPixels;
+
+ // retrieve the divisor in the preferences
+ int userTileSize = Math.max(2, Math.min(3, Preferences.getTileSize()));
+ float divisor = (float)userTileSize;
+
+ // little pading = 10
+ genreSizePx = Math.round(Math.min(screenWidth, screenHeight) / divisor) - 10;
+ genreSpanCount = Math.max(2, Math.round(screenWidth / (float)genreSizePx) );
+
+ switch (userTileSize) {
+ default:
+ case 2: // XL
+ genreSpacing = 20;
+ break;
+ case 3: // L
+ genreSpacing = 15;
+ break;
+ case 4: // M
+ genreSpacing = 10;
+ break;
+ case 5: // S
+ genreSpacing = 6;
+ break;
+ case 6: // XS
+ genreSpacing = 2;
+ break;
+ }
+ genreIsInitialized = true;
+ }
+
+ public void calculateDiscoverSize(Context context) {
+ DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ float screenWidth = metrics.widthPixels;
+ float screenHeight = metrics.heightPixels;
+ float discoverDivisor;
+
+ // retrieve the divisor in the preferences
+ int userTileSize = Math.max(2, Math.min(6, Preferences.getTileSize()));
+
+ switch (userTileSize) {
+ default:
+ case 2: // XL
+ discoverDivisor = 1.0f;
+ break;
+ case 3: // L
+ discoverDivisor = 1.25f;
+ break;
+ case 4: // M
+ discoverDivisor = 1.5f;
+ break;
+ case 5: // S
+ discoverDivisor = 1.75f;
+ break;
+ case 6: // XS
+ discoverDivisor = 2.0f;
+ break;
+ }
+
+ discoverWidthPx = Math.round(Math.min(screenWidth, screenHeight) / discoverDivisor) - 50;
+ discoverHeightPx = Math.round((float)discoverWidthPx * 0.6f);
+ discoverIsInitialized = true;
+ }
+}
diff --git a/app/src/main/res/layout/fragment_home_tab_music.xml b/app/src/main/res/layout/fragment_home_tab_music.xml
index e698b31c..88cb2143 100644
--- a/app/src/main/res/layout/fragment_home_tab_music.xml
+++ b/app/src/main/res/layout/fragment_home_tab_music.xml
@@ -330,13 +330,13 @@
-
+ android:paddingBottom="8dp" />
diff --git a/app/src/main/res/layout/fragment_library.xml b/app/src/main/res/layout/fragment_library.xml
index 9c5f0419..0f4b7149 100644
--- a/app/src/main/res/layout/fragment_library.xml
+++ b/app/src/main/res/layout/fragment_library.xml
@@ -36,7 +36,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:paddingBottom="8dp"
android:visibility="gone"
tools:visibility="visible">
diff --git a/app/src/main/res/layout/item_home_discover_song.xml b/app/src/main/res/layout/item_home_discover_song.xml
index 6e4ccee2..a3df84d7 100644
--- a/app/src/main/res/layout/item_home_discover_song.xml
+++ b/app/src/main/res/layout/item_home_discover_song.xml
@@ -1,13 +1,14 @@
-
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_home_year.xml b/app/src/main/res/layout/item_home_year.xml
index 702c1074..bbc5c721 100644
--- a/app/src/main/res/layout/item_home_year.xml
+++ b/app/src/main/res/layout/item_home_year.xml
@@ -4,13 +4,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:paddingEnd="12dp"
- android:paddingBottom="8dp">
+ android:paddingEnd="8dp"
+ android:paddingBottom="4dp">
4
+
+ - Minuscule
+ - Petite
+ - Moyenne
+ - Large
+ - Défaut
+
+
+ - 6
+ - 5
+ - 4
+ - 3
+ - 2
+
- Ne pas afficher
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 49eb4222..9cc61079 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -432,6 +432,8 @@
Si activé, les pistes favorites seront téléchargées pour l\'écoute hors-ligne.
Synchronisation des pistes favorites pour écoute hors-ligne
Thème
+ Taille des vignettes
+ Données
Données
Géneral
Playlist
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index b9c6587b..ebffd85e 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -279,6 +279,20 @@
- 7
+
+ - Tiny
+ - Small
+ - Medium
+ - Large
+ - Default
+
+
+ - 6
+ - 5
+ - 4
+ - 3
+ - 2
+
- Do not display
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2cb61a4c..08264392 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -450,6 +450,7 @@
If enabled, starred tracks will be downloaded for offline use.
Sync starred tracks for offline use
Theme
+ Tiles size
Data
General
Playlist
diff --git a/app/src/main/res/xml/global_preferences.xml b/app/src/main/res/xml/global_preferences.xml
index 02a47086..0b7c53d6 100644
--- a/app/src/main/res/xml/global_preferences.xml
+++ b/app/src/main/res/xml/global_preferences.xml
@@ -54,6 +54,15 @@
android:defaultValue="false"
android:key="always_on_display" />
+
+
-
-
-
+
From cb4c19757dd575b1f8045b36ec5275a81ed00c62 Mon Sep 17 00:00:00 2001
From: Oliver Tzeng
Date: Tue, 17 Mar 2026 12:45:16 +0800
Subject: [PATCH 3/4] Translated to zh_TW (#494)
* translated to zh_TW
* support zh-TW
* fixed 'apply'
---------
Co-authored-by: eddyizm
---
app/src/main/res/values-zh-rCN | 1 +
app/src/main/res/values-zh-rTW/arrays.xml | 257 ++++++++++
app/src/main/res/values-zh-rTW/strings.xml | 550 +++++++++++++++++++++
app/src/main/res/xml/locale_config.xml | 1 +
4 files changed, 809 insertions(+)
create mode 120000 app/src/main/res/values-zh-rCN
create mode 100644 app/src/main/res/values-zh-rTW/arrays.xml
create mode 100644 app/src/main/res/values-zh-rTW/strings.xml
diff --git a/app/src/main/res/values-zh-rCN b/app/src/main/res/values-zh-rCN
new file mode 120000
index 00000000..d83d3e6e
--- /dev/null
+++ b/app/src/main/res/values-zh-rCN
@@ -0,0 +1 @@
+values-zh
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rTW/arrays.xml b/app/src/main/res/values-zh-rTW/arrays.xml
new file mode 100644
index 00000000..1638da21
--- /dev/null
+++ b/app/src/main/res/values-zh-rTW/arrays.xml
@@ -0,0 +1,257 @@
+
+
+ - 淺色
+ - 深色
+ - 跟隨系統
+
+
+ - light
+ - dark
+ - default
+
+
+
+ - 高
+ - 中
+ - 低
+
+
+ - 500
+ - 250
+ - 125
+
+
+
+ - 高
+ - 中
+ - 低
+
+
+ - -1
+ - 500
+ - 300
+
+
+
+ - 禁用
+ - 128 MiB
+ - 256 MiB
+ - 512 MiB
+ - 1024 MiB
+
+
+ - 0
+ - 128
+ - 256
+ - 512
+ - 1024
+
+
+
+ - 原始
+ - 32 kbps
+ - 48 kbps
+ - 64 kbps
+ - 80 kbps
+ - 96 kbps
+ - 112 kbps
+ - 128 kbps
+ - 160 kbps
+ - 192 kbps
+ - 256 kbps
+ - 320 kbps
+
+
+ - 0
+ - 32
+ - 48
+ - 64
+ - 80
+ - 96
+ - 112
+ - 128
+ - 160
+ - 192
+ - 256
+ - 320
+
+
+
+ - 原始
+ - 32 kbps
+ - 48 kbps
+ - 64 kbps
+ - 80 kbps
+ - 96 kbps
+ - 112 kbps
+ - 128 kbps
+ - 160 kbps
+ - 192 kbps
+ - 256 kbps
+ - 320 kbps
+
+
+ - 0
+ - 32
+ - 48
+ - 64
+ - 80
+ - 96
+ - 112
+ - 128
+ - 160
+ - 192
+ - 256
+ - 320
+
+
+
+ - 原始
+ - 32 kbps
+ - 48 kbps
+ - 64 kbps
+ - 80 kbps
+ - 96 kbps
+ - 112 kbps
+ - 128 kbps
+ - 160 kbps
+ - 192 kbps
+ - 256 kbps
+ - 320 kbps
+
+
+ - 0
+ - 32
+ - 48
+ - 64
+ - 80
+ - 96
+ - 112
+ - 128
+ - 160
+ - 192
+ - 256
+ - 320
+
+
+
+ - 播放原始
+ - Opus
+ - AAC
+ - Mp3
+ - Flac
+
+
+ - raw
+ - opus
+ - aac
+ - mp3
+ - flac
+
+
+
+ - 播放原始
+ - Opus
+ - AAC
+ - Mp3
+ - Flac
+
+
+ - raw
+ - opus
+ - aac
+ - mp3
+ - flac
+
+
+
+ - 下載原始
+ - Opus
+ - AAC
+ - Mp3
+ - Flac
+
+
+ - raw
+ - opus
+ - aac
+ - mp3
+ - flac
+
+
+
+ - 10秒
+ - 5秒
+ - 2秒
+
+
+ - 10
+ - 5
+ - 2
+
+
+
+ - 高
+ - 中
+ - 低
+
+
+ - 18
+ - 12
+ - 6
+
+
+
+ - 禁用
+ - 曲目
+ - 專輯
+ - 自動
+
+
+ - disabled
+ - track
+ - album
+ - auto
+
+
+
+ - 不轉碼
+ - 伺服器設定
+ - Wi-Fi轉碼設定
+ - 行動資料轉碼設定
+
+
+ - 0
+ - 1
+ - 2
+ - 3
+
+
+
+ - 最小
+ - 適中
+ - 積極
+ - 極端
+
+
+ - .1
+ - 1
+ - 4
+ - 8
+
+
+
+ - 不篩選評分
+ - 1 星及以上
+ - 2 星及以上
+ - 3 星及以上
+ - 4 星及以上
+
+
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 00000000..977b0f99
--- /dev/null
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,550 @@
+
+ 如果遇到問題,請存取 https://dontkillmyapp.com。 省電優化選項可能會影響應用程式的性能,網站上提供瞭如何禁用這些選項的詳細說明。
+ 請禁用針對鎖定畫面播放的電池優化。
+ 電池優化
+ 離線模式
+ 新增到播放清單
+ 新增到序列
+ 全部下載
+ 查看該藝術家
+ 即時混聽
+ 下一首播放
+ 移除所有
+ 分享
+ 隨機播放
+ 專輯
+ 瀏覽專輯
+ 檢索藝術家時出錯
+ 已下載的專輯
+ 最常播放的專輯
+ 新發行的專輯
+ 最近新增的專輯
+ 最近播放的專輯
+ 收藏的專輯
+ 專輯
+ 更多相似
+ 播放
+ 發行日期:%1$s
+ 發行日期:%1$s(原版發行於 %2$s)
+ 隨機播放
+ %1$d 首歌曲 • %2$d 分鐘
+ Tempus
+ 正在搜尋...
+ 即時混聽
+ 隨機播放
+ 藝術家
+ 瀏覽藝術家
+ 檢索藝術家的電臺時出錯
+ 檢索藝術家歌曲時出錯
+ 已下載的藝術家
+ 收藏的藝術家
+ 藝術家
+ 電臺
+ 隨機播放
+ 切換佈局
+ 更多類似
+ 專輯
+ 更多
+ 藝術家簡介
+ 最常播放的歌曲
+ 查看全部
+ %1$s • %2$s
+ Tempus 資源連結
+ 已將 %1$s 複製到剪貼簿
+ 資源連結:%1$s
+ 無法開啟該專輯
+ 無法開啟該藝術家頁
+ 無法開啟該播放清單
+ 無法開啟該歌曲
+ 不支援的資源連結
+ 專輯 UID
+ 藝術家 UID
+ 流派 UID
+ 播放清單 UID
+ 歌曲 UID
+ 資源 UID
+ 年份 UID
+ 忽略
+ 不再詢問
+ 禁用
+ 載入中...
+ 取消
+ 啟用流量節省
+ 確定
+ 已限制通過 Wi-Fi 以外的連接存取 Subsonic 伺服器。 欲阻止此警告對話框再次出現,請在應用程式設定中禁用連接檢查。
+ Wi-Fi 網路未連接
+ 隨機
+ 取消
+ 繼續
+ 請注意,繼續執行此操作將永久刪除從所有伺服器下載的所有已儲存的項目。
+ 刪除已儲存的項目
+ 沒有可用的歌詞
+ 第 %1$s 張光碟 - %2$s
+ 第 %1$s 張光碟
+ 取消
+ 下載
+ 該資料夾中的所有歌曲將被下載。子資料夾中的歌曲將不會被下載。
+ 下載歌曲
+ 設定歌曲下載位置
+ 下載歌曲後,您可以在這裡找到它
+ 還沒有下載!
+ %1$s • %2$s 個項目
+ %1$s 個項目
+ 刷新下載項
+ 沒有遺漏的下載項。
+ 設定下載目錄以刷新下載內容。
+
+ - 已移除 %d 個缺失的下載項。
+ - 已移除 %d 個缺失的下載項。
+
+ 隨機播放全部
+ 要使更改生效,請重新啟動應用程式。
+ 更改已下載檔案的目錄將會立即刪除以前已下載的所有檔案。
+ 選擇儲存選項
+ 目錄
+ 外部
+ 內部
+ 下載
+ 新增到序列
+ 下一首播放
+ 移除
+ 移除所有
+ 隨機播放
+
+ 啟用
+ 均衡器
+ 此設備不支援
+ 重置
+ 必需
+ 必須是 http 或 https 前綴
+ 取消收藏
+ 收藏
+ 下載
+ 篩選藝術家
+ 選擇兩個或多個過濾器
+ 篩選
+ 篩選流派
+ 正在讀取資料夾中的歌曲...
+ 資料夾內未發現歌曲
+ 正在播放 %d 首歌曲
+ (%1$d)
+ (+%1$d)
+ 流派目錄
+ 瀏覽流派
+ 稍後提醒
+ 支援項目
+ 立即下載
+ GitHub 上發佈了新版本。
+ 有可用更新
+ 定製首頁
+ 取消
+ 重置
+ 儲存
+ 請重啟應用程式以套用更改。
+ 首頁排序
+ 音樂
+ 播客
+ 電臺
+ 您最喜歡的藝術家的熱門歌曲
+ 從您喜歡的歌曲開始混聽
+ 新增新的電臺
+ 新增新的播客頻道
+
+ - %d 個待同步專輯
+ - %d 個待同步專輯
+
+ 標記為收藏的專輯可離線使用
+ 同步收藏的專輯
+ 你收藏的藝術家有未下載的歌曲
+ 同步收藏的藝術家
+
+ - %d 個待同步藝術家
+ - %d 個待同步藝術家
+
+ 取消
+ 下載
+
+ - %d 首待同步歌曲
+ - %d 首待同步歌曲
+
+ 下載這些歌曲可能需要大量行動資料流量
+ 似乎有一些收藏的歌曲需要同步
+ 最佳
+ 發現
+ 隨機播放全部
+ 重溫舊曲
+ 網路廣播電臺
+ 上月
+ 最近播放
+ 查看全部
+ 上週
+ 去年
+ 為您定製
+ 最常播放
+ 查看全部
+ 新發行
+ 最新播客
+ 播放清單
+ 頻道
+ 查看全部
+ 廣播電臺
+ 最近新增
+ 查看全部
+ 分享
+ ★ 收藏的專輯
+ 查看全部
+ ★ 收藏的藝術家
+ 查看全部
+ ★ 收藏的歌曲
+ 查看全部
+ 你最喜歡的歌曲
+ •
+ --
+ 專輯
+ 查看全部
+ 藝術家
+ 查看全部
+ 流派
+ 查看全部
+ 音樂資料夾
+ 播放清單
+ 查看全部
+ 尚未新增伺服器
+ Subsonic 伺服器
+ Subsonic 伺服器
+ 投送
+ 新增
+ 新增到播放清單
+ 全部下載
+ 下載
+ 全部
+ 已下載
+ 專輯
+ 藝術家
+ 流派
+ 歌曲
+ 年份
+ 首頁
+ 上月
+ 上週
+ 去年
+ 曲庫
+ 新增到首頁
+ 專輯評分
+ 搜尋
+ 設定
+ 專輯數量
+ 藝術家
+ 最早收藏
+ 最多播放
+ 最近收藏
+ 名稱
+ 隨機
+ 最近新增
+ 最近播放
+ 年份
+ 從首頁移除
+ 下載離線歌詞
+ 暫無歌詞可供下載。
+ 離線歌詞已儲存。
+ 已下載的離線歌詞
+ %1$.2fx
+ 清空序列
+ 載入序列
+ 儲存序列
+ 儲存序列到播放清單
+ 伺服器優先級
+ 正在轉碼
+ 已請求轉碼
+ 未知格式
+ 播放清單目錄
+ 瀏覽播放清單
+ 尚未建立播放清單
+ 取消
+ 新建
+ 新增到播放清單
+ 未能將歌曲新增到播放清單
+ 將歌曲新增到播放清單
+ 所有歌曲已存在,無需重複新增
+ %1$d 首歌曲 • %2$s
+ 時長 • %1$s
+ 長按刪除
+ 播放清單名稱
+ 取消
+ 刪除
+ 儲存
+ 編輯播放清單
+ 播放
+ 隨機播放
+ 播放清單 • %1$d 首歌曲
+ 新增到序列
+ 刪除
+ 下載
+ 前往該頻道
+ 下一首播放
+ 移除
+ 頻道
+ 瀏覽頻道
+ RSS 網址
+ 播客頻道
+ 此伺服器不支援播客。
+ 描述
+ 劇集
+ 沒有可用的劇集
+ 您的請求已發送至伺服器
+ 單擊以隱藏該部分\n重啟應用程式後生效
+ 新增頻道後,您將在此處找到它
+ 未找到播客!
+ %1$s • %2$s
+ 伺服器不支援網路電臺管理。
+ 已新增電臺
+ 電臺首頁 URL
+ 電臺名稱
+ 廣播流 URL
+ 取消
+ 刪除
+ 儲存
+ 網路廣播電臺
+ 已更新電臺
+ 單擊以隱藏該部分\n重啟應用程式後生效
+ 新增廣播電臺後,您可以在此處找到它
+ 沒有找到電臺!
+ 取消
+ 儲存
+ 評分
+ 搜尋標題、藝術家或專輯
+ 輸入至少三個字符
+ 啟用後將按時間排序搜尋,關閉則按名稱排序。
+ 按時間排序最近搜尋
+ 專輯
+ 藝術家
+ 歌曲
+ 長按刪除
+ 低安全性
+ 本地 URL
+ 伺服器名稱
+ 密碼
+ 伺服器位址
+ 使用者名稱
+ 取消
+ 刪除
+ 儲存
+ 新增伺服器
+ 取消
+ 前往登入
+ 仍然繼續
+ 請求的伺服器不可用。 如果您選擇繼續,此對話框在接下來的一個小時內將不會再次出現。
+ 伺服器無法存取
+ Tempus 是 Subsonic 的開源輕量級音樂客戶端,專為 Android 設計和構建。
+ 關於
+ 顯示專輯詳情
+ 啟用後將在專輯頁顯示流派、歌曲數量等資訊
+ 允許新增重複歌曲到播放清單
+ 啟用後則新增到播放清單時將不再檢查重複內容。
+ 保持螢幕常亮
+ 均衡器
+ 開啟搭載均衡器
+ 按專輯數量排序藝術家
+ 啟用後按專輯數量排序;關閉則按名稱排序。
+ 顯示音訊品質
+ 顯示歌曲的位元率和音訊格式。
+ 轉碼格式
+ 啟用後 Tempus 將不會強制使用下面的轉碼設定下載歌曲。
+ 優先考慮伺服器上用於流式傳輸的設定
+ 啟用後 Tempus 將下載轉碼後的歌曲。
+ 下載轉碼後的歌曲
+ 啟用後將發送請求到伺服器以查詢歌曲的大概持續時間。
+ 大概內容長度
+ 用於下載的轉碼格式
+ 行動資料下的轉碼格式
+ Wi-Fi 下的轉碼格式
+ 啟用後 Tempus 將不會強制使用下面的轉碼設定流式傳輸歌曲。
+ 優先考慮伺服器轉碼設定
+ 歌曲轉碼設定優先級設定為伺服器
+ 自動下載歌詞
+ 自動儲存可用歌詞,以便離線時查看。
+ 快取策略
+ 為了使更改生效,您必須手動重新啟動應用程式。
+ 選擇一個音樂下載目錄
+ 清空下載資料夾
+ 允許在播放清單結束後,播放相似的歌曲。
+ 連續播放
+ 圖片快取大小
+ 為了減少資料消耗,請避免下載封面。
+ 限制行動資料使用
+ 繼續當前操作將導致所有已儲存的項目被永久刪除。
+ 刪除已儲存的項目
+ 下載資料夾已清除。
+ 已設定下載資料夾
+ 下載儲存
+ https://github.com/eddyizm/tempus
+ 關注開發進展
+ Github
+ 更新
+ GitHub 版本預設會自動檢查 APK 更新。您可以關閉此開關以禁用自動檢查。
+ 請存取 Github 以檢查更新
+ 設定圖像解析度
+ 顯示評分
+ 啟用後則顯示項目的評分和收藏狀態。
+ 語言
+ 註銷登入
+ 用於下載的位元率
+ 行動資料下的位元率
+ Wi-Fi 下的位元率
+ 媒體檔案快取大小
+ 顯示音樂目錄
+ 啟用後則顯示音樂目錄部分。 請注意,要使資料夾導航正常工作,伺服器必須支援此功能。
+ 顯示播客
+ 啟用後則顯示播客部分。
+ 同步定時器
+ 啟用後將允許當前使用者儲存其播放序列,並能夠在開啟應用程式時載入儲存狀態。
+ 同步當前使用者的播放序列
+ 顯示電臺
+ 啟用後,則顯示電臺部分。
+ 設定播放增益模式
+ 圓角
+ 圓角大小
+ 設定圓角的大小。
+ 啟用後則為所有渲染的封面設定圓角。更改將在應用程式重新啟動後生效。
+ 正在掃描:已發現 %1$d 首歌曲
+ 掃描曲庫
+ 啟用音樂記錄
+ 設定下載資料夾
+ 啟用音樂共享
+ 顯示隨機按鈕
+ 啟用後,在迷你播放器中顯示隨機播放按鈕,並移除收藏按鈕。
+ 顯示歌曲評分
+ 啟用後歌曲詳情頁將顯示五星評分。\n\n*需重啟應用程式後生效
+ 播放快取大小
+ 快取目錄設定
+ 請注意,音樂記錄同時也依賴於伺服器是否能夠接收這些資料。
+ 播放增益(Replay gain)允許您通過調整音軌的音量,以獲得始終如一的聆聽體驗。 僅當歌曲標籤包含必要的元資料時,此設定才有效。
+ 音樂記錄(Scrobbling)允許您的設備將您收聽的歌曲的相關資訊發送到音樂伺服器。 這些資訊有助於基於您的音樂偏好生成個性化推薦。
+ 允許使用者通過連結共享音樂。 該功能需要伺服器端支援並啟用,並且僅限於單首歌曲、專輯和序列。
+ 收聽電臺,即時混合和隨機播放時,低於特定評分的歌曲將會被忽略。
+ %1$s \n已使用: %2$s MiB
+ 返回當前使用者的播放序列狀態。 這包括播放序列中的歌曲、正在播放的歌曲以及歌曲播放進度。需要伺服器支援此功能。
+ 轉碼模式優先級設定。 如果設定為「播放原始」,檔案的位元率將不會更改。
+ 下載轉碼後的媒體。 啟用後將不會下載原始資料,而是使用以下設定。\n如果「用於下載的轉碼格式」設定為「下載原始」,則檔案的位元率不會更改。
+ 當檔案即時轉碼時,客戶端通常不會顯示歌曲長度。 可以向支援該功能的伺服器發送請求,大概正在播放的歌曲的持續時間,但可能回應變慢。
+ https://github.com/eddyizm/tempus/discussions
+ 加入社群討論並取得幫助
+ 使用者支援
+ 啟用後將下載收藏的專輯以供離線使用。
+ 下載收藏的專輯以供離線使用
+ 啟用後將自動下載收藏的藝術家以供離線使用。
+ 同步收藏的藝術家以供離線使用
+ 啟用後將下載收藏的歌曲以供離線使用。
+ 同步收藏的歌曲以供離線使用
+ 調整音訊設定
+ 系統均衡器
+ 系統語言
+ 主題
+ 資料
+ 通用
+ 播放清單
+ 評分
+ 播放增益
+ 音樂記錄
+ 分享
+ 根據評分忽略歌曲
+ 根據歌曲評分篩選:
+ 同步
+ 轉碼
+ 轉碼下載
+ 界面
+ 轉碼下載
+ 3.1.0
+ 版本
+ 在通過行動網路進行流式傳輸之前請求使用者確認。
+ 提示僅通過 Wi-Fi 進行流式傳輸
+ 複製連結
+ 刪除分享
+ 更新分享
+ 永不過期
+ 到期日期:%1$s
+ 不支援分享或未啟用
+ 描述
+ 截止日期
+ 取消
+ 儲存
+ 分享
+ 新增到播放清單
+ 新增到序列
+ 下載
+ 檢索相簿時出錯
+ 檢索藝術家時出錯
+ 前往該專輯
+ 前往該藝術家
+ 即時混合
+ 下一首播放
+ 評分
+ 移除
+ 分享
+ 已下載
+ 最常播放的歌曲
+ 最近新增的歌曲
+ 最近播放的歌曲
+ 已收藏的歌曲
+ %1$s 的熱門歌曲
+ 年份 %1$d
+ %1$s • %2$s %3$s
+
+ - 正在下載 %d 首歌曲
+ - 正在下載 %d 首歌曲
+
+ 下載收藏的專輯可能會消耗大量行動資料流量。
+ 同步收藏的專輯
+ 下載收藏的藝術家可能會消耗大量行動資料流量。
+ 同步收藏的藝術家
+ 取消
+ 繼續
+ 繼續並下載
+ 下載收藏的歌曲可能會消耗大量行動資料流量。
+ 同步收藏的歌曲
+ 要使更改生效,請重新啟動應用程式。
+ 切換快取檔案的儲存路徑可能會導致原位置儲存的快取檔案被清空。
+ 選擇儲存位置
+ 外部
+ 內部
+ https://ko-fi.com/eddyizm
+ 專輯
+ 藝術家
+ 位深
+ 位元率
+ 內容類型
+ 確定
+ 歌曲資訊
+ 碟片編號
+ 持續時間
+ 流派
+ 路徑
+ 採樣率
+ 大小
+ 後綴
+ 該檔案已使用 Subsonic API 下載。 檔案的編碼和位元率與原始檔一致。
+ 本應用程式將請求伺服器對檔案進行轉碼並修改其位元率。 使用者請求的編解碼器是%1$s,位元率為%2$s。 對所選格式的檔案的編碼和位元率的任何潛在更改都將由伺服器處理,伺服器可能支援也可能不支援該操作。
+ 本應用程式只會讀取伺服器提供的原始檔案。 本應用程式將明確向伺服器請求具有原始源位元率的未轉碼檔案。
+ 要播放的檔案品質取決於伺服器設定。 本應用程式不會強制選擇任何用於潛在轉碼的編碼和位元率。
+ 本應用程式將請求伺服器修改檔案的位元率。 使用者請求的位元率為%1$s,而原始檔的編碼將保持不變。 對所選格式的檔案位元率的任何更改都將由伺服器完成,伺服器可能支援也可能不支援該操作。
+ 本應用程式將請求伺服器對檔案進行轉碼。 使用者請求的編解碼器是%1$s,而位元率將與原始檔相同。 將檔案轉碼為所選格式的可能性取決於伺服器,因為它可能支援也可能不支援該操作。
+ 標題
+ 歌曲編號
+ 轉碼內容類型
+ 轉碼後綴
+ 年份
+ unDraw
+ 特別感謝 unDraw,沒有它提供的插圖,我們的應用程式不可能會如此精美。
+ https://undraw.co/
+ 專輯封面
+ 下一首
+ 播放或暫停
+ 上一首
+ 更改循環模式
+ 切換隨機播放
+ Tempus 小組件
+ 未播放
+ 開啟 Tempus
+ 0:00
+ 0:00
+
diff --git a/app/src/main/res/xml/locale_config.xml b/app/src/main/res/xml/locale_config.xml
index ead4c673..63dd2999 100644
--- a/app/src/main/res/xml/locale_config.xml
+++ b/app/src/main/res/xml/locale_config.xml
@@ -4,6 +4,7 @@
+
From 8db6797eaa8358fea1559b39c65f38e17aeeee0d Mon Sep 17 00:00:00 2001
From: eddyizm
Date: Mon, 16 Mar 2026 22:03:36 -0700
Subject: [PATCH 4/4] fix: duplicate line in fr settings
---
app/src/main/res/values-fr/strings.xml | 1 -
1 file changed, 1 deletion(-)
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 9cc61079..7d441df1 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -434,7 +434,6 @@
Thème
Taille des vignettes
Données
- Données
Géneral
Playlist
Note