Compare commits

...

17 Commits

Author SHA1 Message Date
dkanada
7607a7c315 Merge pull request #191 from jellyfin/dkanada-patch-2
New release
2019-11-10 02:02:27 +09:00
Budkhuu
4d92f5fc50 Translated using Weblate (Mongolian)
Currently translated at 65.1% (209 of 321 strings)

Translation: Jellyfin/Jellyfin AndroidTV
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-androidtv/mn/
2019-11-08 01:15:10 -05:00
dkanada
08f5601449 new release 2019-11-08 15:14:36 +09:00
dkanada
18f1f69000 Merge pull request #190 from thornbill/theme-manager
Cleanup theme manager
2019-11-08 11:42:44 +09:00
Bill Thornton
511afe1c22 Cleanup theme manager 2019-11-07 14:12:39 -05:00
dkanada
25f732c72a Merge pull request #188 from thornbill/add-server-crash
Fix version check when no servers in response
2019-11-08 03:23:21 +09:00
dkanada
fc944cc77d Merge pull request #187 from thornbill/images
Fix incorrect image types and aspect ratios
2019-11-08 03:21:12 +09:00
dkanada
47fbd86278 Merge pull request #189 from thornbill/fix-delayed-message
Fix using DelayedMessage on not the main ui thread
2019-11-07 19:20:37 +09:00
Bill Thornton
b656935ce6 Fix using DelayedMessage on not the main ui thread 2019-11-07 01:17:29 -05:00
Budkhuu
49684b5eac Added translation using Weblate (Mongolian) 2019-11-06 23:31:39 -05:00
Bill Thornton
3b6689f2a3 Fix version check when no servers in response 2019-11-06 23:27:30 -05:00
Bill Thornton
613e9c4e57 Force aspect ratio for LiveTvProgram movies 2019-11-06 21:27:06 -05:00
Bill Thornton
cda5970488 Fix program image type 2019-11-06 19:35:15 -05:00
Bill Thornton
79669bfee1 Fix non-translated strings and formatting 2019-11-06 19:27:22 -05:00
Bill Thornton
6cddce7ada Force aspect ratio for CollectionFolder types 2019-11-06 19:12:19 -05:00
Bill Thornton
dab9bb1d8d Fix formatting issues 2019-11-06 19:12:19 -05:00
jeannin matthieu
a25e380476 Translated using Weblate (French)
Currently translated at 99.1% (318 of 321 strings)

Translation: Jellyfin/Jellyfin AndroidTV
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-androidtv/fr/
2019-11-05 14:15:02 -05:00
15 changed files with 625 additions and 178 deletions

View File

@@ -1,5 +1,5 @@
apply plugin: 'com.android.application'
def version = "0.10.1"
def version = "0.10.2"
android {
compileSdkVersion 28
@@ -8,7 +8,7 @@ android {
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
versionCode 903
versionCode 904
versionName version
}

View File

@@ -1,6 +1,5 @@
package org.jellyfin.androidtv.browsing;
import android.os.Bundle;
import androidx.leanback.widget.ArrayObjectAdapter;
import androidx.leanback.widget.HeaderItem;
import androidx.leanback.widget.ListRow;
@@ -39,29 +38,13 @@ import org.jellyfin.apiclient.model.querying.LatestItemsQuery;
import org.jellyfin.apiclient.model.querying.NextUpQuery;
import org.jellyfin.apiclient.model.results.TimerInfoDtoResult;
/**
* Created by Eric on 12/4/2014.
*/
public class BrowseViewFragment extends EnhancedBrowseFragment {
boolean isLiveTvLibrary;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
}
private boolean isLiveTvLibrary;
@Override
protected void setupQueries(final IRowLoader rowLoader) {
String type = mFolder.getCollectionType() != null ? mFolder.getCollectionType().toLowerCase() : "";
switch (type)
{
switch (type) {
case "movies":
itemTypeString = "Movie";
@@ -77,15 +60,15 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
resumeMovies.setFilters(new ItemFilter[]{ItemFilter.IsResumable});
resumeMovies.setSortBy(new String[]{ItemSortBy.DatePlayed});
resumeMovies.setSortOrder(SortOrder.Descending);
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_continue_watching), resumeMovies, 0, new ChangeTriggerType[] {ChangeTriggerType.MoviePlayback}));
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_continue_watching), resumeMovies, 0, new ChangeTriggerType[]{ChangeTriggerType.MoviePlayback}));
//Latest
LatestItemsQuery latestMovies = new LatestItemsQuery();
latestMovies.setFields(new ItemFields[] {ItemFields.PrimaryImageAspectRatio, ItemFields.Overview});
latestMovies.setFields(new ItemFields[]{ItemFields.PrimaryImageAspectRatio, ItemFields.Overview});
latestMovies.setParentId(mFolder.getId());
latestMovies.setLimit(50);
latestMovies.setImageTypeLimit(1);
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_latest), latestMovies, new ChangeTriggerType[] {ChangeTriggerType.MoviePlayback, ChangeTriggerType.LibraryUpdated}));
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_latest), latestMovies, new ChangeTriggerType[]{ChangeTriggerType.MoviePlayback, ChangeTriggerType.LibraryUpdated}));
//Favorites
StdItemQuery favorites = new StdItemQuery();
@@ -95,7 +78,7 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
favorites.setImageTypeLimit(1);
favorites.setFilters(new ItemFilter[]{ItemFilter.IsFavorite});
favorites.setSortBy(new String[]{ItemSortBy.SortName});
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_favorites), favorites, 60, new ChangeTriggerType[] {ChangeTriggerType.LibraryUpdated, ChangeTriggerType.FavoriteUpdate}));
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_favorites), favorites, 60, new ChangeTriggerType[]{ChangeTriggerType.LibraryUpdated, ChangeTriggerType.FavoriteUpdate}));
//Collections
StdItemQuery collections = new StdItemQuery();
@@ -104,7 +87,7 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
collections.setImageTypeLimit(1);
//collections.setParentId(mFolder.getId());
collections.setSortBy(new String[]{ItemSortBy.SortName});
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_collections), collections, 60, new ChangeTriggerType[] {ChangeTriggerType.LibraryUpdated}));
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_collections), collections, 60, new ChangeTriggerType[]{ChangeTriggerType.LibraryUpdated}));
rowLoader.loadRows(mRows);
break;
@@ -117,8 +100,8 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
nextUpQuery.setLimit(50);
nextUpQuery.setParentId(mFolder.getId());
nextUpQuery.setImageTypeLimit(1);
nextUpQuery.setFields(new ItemFields[] {ItemFields.PrimaryImageAspectRatio, ItemFields.Overview});
mRows.add(new BrowseRowDef(mApplication.getResources().getString(R.string.lbl_next_up), nextUpQuery, new ChangeTriggerType[] {ChangeTriggerType.TvPlayback}));
nextUpQuery.setFields(new ItemFields[]{ItemFields.PrimaryImageAspectRatio, ItemFields.Overview});
mRows.add(new BrowseRowDef(mApplication.getResources().getString(R.string.lbl_next_up), nextUpQuery, new ChangeTriggerType[]{ChangeTriggerType.TvPlayback}));
//Premieres
if (mApplication.getPrefs().getBoolean("pref_enable_premieres", false)) {
@@ -140,13 +123,13 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
//Latest content added
LatestItemsQuery latestSeries = new LatestItemsQuery();
latestSeries.setFields(new ItemFields[] {ItemFields.PrimaryImageAspectRatio, ItemFields.Overview});
latestSeries.setFields(new ItemFields[]{ItemFields.PrimaryImageAspectRatio, ItemFields.Overview});
latestSeries.setIncludeItemTypes(new String[]{"Episode"});
latestSeries.setGroupItems(true);
latestSeries.setParentId(mFolder.getId());
latestSeries.setLimit(50);
latestSeries.setImageTypeLimit(1);
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_latest), latestSeries, new ChangeTriggerType[] {ChangeTriggerType.LibraryUpdated}));
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_latest), latestSeries, new ChangeTriggerType[]{ChangeTriggerType.LibraryUpdated}));
//Favorites
StdItemQuery tvFavorites = new StdItemQuery();
@@ -156,7 +139,7 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
tvFavorites.setImageTypeLimit(1);
tvFavorites.setFilters(new ItemFilter[]{ItemFilter.IsFavorite});
tvFavorites.setSortBy(new String[]{ItemSortBy.SortName});
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_favorites), tvFavorites, 60, new ChangeTriggerType[] {ChangeTriggerType.LibraryUpdated, ChangeTriggerType.FavoriteUpdate}));
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_favorites), tvFavorites, 60, new ChangeTriggerType[]{ChangeTriggerType.LibraryUpdated, ChangeTriggerType.FavoriteUpdate}));
rowLoader.loadRows(mRows);
break;
@@ -164,13 +147,13 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
//Latest
LatestItemsQuery latestAlbums = new LatestItemsQuery();
latestAlbums.setFields(new ItemFields[] {ItemFields.PrimaryImageAspectRatio, ItemFields.Overview});
latestAlbums.setFields(new ItemFields[]{ItemFields.PrimaryImageAspectRatio, ItemFields.Overview});
latestAlbums.setIncludeItemTypes(new String[]{"Audio"});
latestAlbums.setGroupItems(true);
latestAlbums.setImageTypeLimit(1);
latestAlbums.setParentId(mFolder.getId());
latestAlbums.setLimit(50);
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_latest), latestAlbums, new ChangeTriggerType[] {ChangeTriggerType.LibraryUpdated}));
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_latest), latestAlbums, new ChangeTriggerType[]{ChangeTriggerType.LibraryUpdated}));
//Last Played
StdItemQuery lastPlayed = new StdItemQuery();
@@ -183,7 +166,7 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
lastPlayed.setSortOrder(SortOrder.Descending);
lastPlayed.setEnableTotalRecordCount(false);
lastPlayed.setLimit(50);
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_last_played), lastPlayed, 0, false, true, new ChangeTriggerType[] {ChangeTriggerType.MusicPlayback, ChangeTriggerType.LibraryUpdated}));
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_last_played), lastPlayed, 0, false, true, new ChangeTriggerType[]{ChangeTriggerType.MusicPlayback, ChangeTriggerType.LibraryUpdated}));
//Favorites
StdItemQuery favAlbums = new StdItemQuery();
@@ -193,17 +176,17 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
favAlbums.setImageTypeLimit(1);
favAlbums.setFilters(new ItemFilter[]{ItemFilter.IsFavorite});
favAlbums.setSortBy(new String[]{ItemSortBy.SortName});
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_favorites), favAlbums, 60, false, true, new ChangeTriggerType[] {ChangeTriggerType.LibraryUpdated, ChangeTriggerType.FavoriteUpdate}));
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_favorites), favAlbums, 60, false, true, new ChangeTriggerType[]{ChangeTriggerType.LibraryUpdated, ChangeTriggerType.FavoriteUpdate}));
//AudioPlaylists
StdItemQuery playlists = new StdItemQuery(new ItemFields[] {ItemFields.PrimaryImageAspectRatio, ItemFields.CumulativeRunTimeTicks});
StdItemQuery playlists = new StdItemQuery(new ItemFields[]{ItemFields.PrimaryImageAspectRatio, ItemFields.CumulativeRunTimeTicks});
playlists.setIncludeItemTypes(new String[]{"Playlist"});
playlists.setMediaTypes(new String[] {"Audio"});
playlists.setMediaTypes(new String[]{"Audio"});
playlists.setImageTypeLimit(1);
playlists.setRecursive(true);
playlists.setSortBy(new String[]{ItemSortBy.DateCreated});
playlists.setSortOrder(SortOrder.Descending);
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_playlists), playlists, 60, false, true, new ChangeTriggerType[] {ChangeTriggerType.LibraryUpdated}, QueryType.AudioPlaylists));
mRows.add(new BrowseRowDef(mApplication.getString(R.string.lbl_playlists), playlists, 60, false, true, new ChangeTriggerType[]{ChangeTriggerType.LibraryUpdated}, QueryType.AudioPlaylists));
rowLoader.loadRows(mRows);
break;
@@ -214,7 +197,7 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
//On now
RecommendedProgramQuery onNow = new RecommendedProgramQuery();
onNow.setIsAiring(true);
onNow.setFields(new ItemFields[] {ItemFields.Overview, ItemFields.PrimaryImageAspectRatio, ItemFields.ChannelInfo});
onNow.setFields(new ItemFields[]{ItemFields.Overview, ItemFields.PrimaryImageAspectRatio, ItemFields.ChannelInfo});
onNow.setUserId(TvApp.getApplication().getCurrentUser().getId());
onNow.setImageTypeLimit(1);
onNow.setEnableTotalRecordCount(false);
@@ -261,7 +244,7 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
// Also get scheduled recordings for next 24 hours
final TimerQuery scheduled = new TimerQuery();
TvApp.getApplication().getApiClient().GetLiveTvTimersAsync(scheduled, new Response<TimerInfoDtoResult>(){
TvApp.getApplication().getApiClient().GetLiveTvTimersAsync(scheduled, new Response<TimerInfoDtoResult>() {
@Override
public void onResponse(TimerInfoDtoResult response) {
List<BaseItemDto> nearTimers = new ArrayList<>();
@@ -274,7 +257,7 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
programInfo = new BaseItemDto();
programInfo.setId(timer.getId());
programInfo.setChannelName(timer.getChannelName());
programInfo.setName(Utils.getSafeValue(timer.getName(),"Unknown"));
programInfo.setName(Utils.getSafeValue(timer.getName(), "Unknown"));
TvApp.getApplication().getLogger().Warn("No program info for timer %s. Creating one...", programInfo.getName());
programInfo.setType("Program");
programInfo.setTimerId(timer.getId());
@@ -309,11 +292,11 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
recordings.setFields(new ItemFields[]{ItemFields.Overview, ItemFields.PrimaryImageAspectRatio});
recordings.setUserId(TvApp.getApplication().getCurrentUser().getId());
recordings.setEnableImages(true);
mRows.add(new BrowseRowDef("Recent Recordings", recordings, 50));
mRows.add(new BrowseRowDef(mActivity.getString(R.string.lbl_recent_recordings), recordings, 50));
//All Recordings by group - will only be there for non-internal TV
RecordingGroupQuery recordingGroups = new RecordingGroupQuery();
recordingGroups.setUserId(TvApp.getApplication().getCurrentUser().getId());
mRows.add(new BrowseRowDef("All Recordings", recordingGroups));
mRows.add(new BrowseRowDef(mActivity.getString(R.string.lbl_all_recordings), recordingGroups));
rowLoader.loadRows(mRows);
//Now insert our smart rows
@@ -384,7 +367,7 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
ItemQuery rowQuery = new StdItemQuery();
rowQuery.setParentId(item.getId());
rowQuery.setUserId(userId);
rows.add(new BrowseRowDef(item.getName(), rowQuery, 60, new ChangeTriggerType[] {ChangeTriggerType.LibraryUpdated}));
rows.add(new BrowseRowDef(item.getName(), rowQuery, 60, new ChangeTriggerType[]{ChangeTriggerType.LibraryUpdated}));
}
}
@@ -398,8 +381,6 @@ public class BrowseViewFragment extends EnhancedBrowseFragment {
});
break;
}
}
@Override

View File

@@ -124,31 +124,76 @@ public class BaseRowItem {
return baseItem;
}
public BaseItemPerson getPerson() { return person; }
public ChapterItemInfo getChapterInfo() { return chapterInfo; }
public ServerInfo getServerInfo() { return serverInfo; }
public UserDto getUser() { return user; }
public SearchHint getSearchHint() { return searchHint; }
public ChannelInfoDto getChannelInfo() { return channelInfo; }
public BaseItemDto getProgramInfo() { return baseItem; }
public BaseItemDto getRecordingInfo() { return baseItem; }
public SeriesTimerInfoDto getSeriesTimerInfo() { return seriesTimerInfo; }
public GridButton getGridButton() { return gridButton; }
public boolean isChapter() { return type == ItemType.Chapter; }
public boolean isPerson() { return type == ItemType.Person; }
public boolean isBaseItem() { return type == ItemType.BaseItem; }
public boolean getPreferParentThumb() { return preferParentThumb; }
public ItemType getItemType() { return type; }
public BaseItemPerson getPerson() {
return person;
}
public ChapterItemInfo getChapterInfo() {
return chapterInfo;
}
public ServerInfo getServerInfo() {
return serverInfo;
}
public UserDto getUser() {
return user;
}
public SearchHint getSearchHint() {
return searchHint;
}
public ChannelInfoDto getChannelInfo() {
return channelInfo;
}
public BaseItemDto getProgramInfo() {
return baseItem;
}
public BaseItemDto getRecordingInfo() {
return baseItem;
}
public SeriesTimerInfoDto getSeriesTimerInfo() {
return seriesTimerInfo;
}
public GridButton getGridButton() {
return gridButton;
}
public boolean isChapter() {
return type == ItemType.Chapter;
}
public boolean isPerson() {
return type == ItemType.Person;
}
public boolean isBaseItem() {
return type == ItemType.BaseItem;
}
public boolean getPreferParentThumb() {
return preferParentThumb;
}
public ItemType getItemType() {
return type;
}
public boolean isFolder() {
return type == ItemType.BaseItem && baseItem != null && baseItem.getIsFolderItem();
}
public boolean showCardInfoOverlay() {return type == ItemType.BaseItem && baseItem != null
&& ("Folder".equals(baseItem.getType()) || "PhotoAlbum".equals(baseItem.getType()) || "RecordingGroup".equals(baseItem.getType())
|| "UserView".equals(baseItem.getType()) || "CollectionFolder".equals(baseItem.getType()) || "Photo".equals(baseItem.getType())
|| "Video".equals(baseItem.getType()) || "Person".equals(baseItem.getType()) || "Playlist".equals(baseItem.getType())
|| "MusicArtist".equals(baseItem.getType()));
public boolean showCardInfoOverlay() {
return type == ItemType.BaseItem && baseItem != null
&& ("Folder".equals(baseItem.getType()) || "PhotoAlbum".equals(baseItem.getType()) || "RecordingGroup".equals(baseItem.getType())
|| "UserView".equals(baseItem.getType()) || "CollectionFolder".equals(baseItem.getType()) || "Photo".equals(baseItem.getType())
|| "Video".equals(baseItem.getType()) || "Person".equals(baseItem.getType()) || "Playlist".equals(baseItem.getType())
|| "MusicArtist".equals(baseItem.getType()));
}
public boolean isValid() {
@@ -180,8 +225,8 @@ public class BaseRowItem {
default:
return getPrimaryImageUrl(maxHeight);
}
default:
return getPrimaryImageUrl(maxHeight);
default:
return getPrimaryImageUrl(maxHeight);
}
}
@@ -206,8 +251,11 @@ public class BaseRowItem {
case SeriesTimer:
return ImageUtils.getResourceUrl(R.drawable.tile_land_series_timer);
case SearchHint:
return Utils.isNonEmpty(searchHint.getPrimaryImageTag()) ? ImageUtils.getImageUrl(searchHint.getItemId(), ImageType.Primary, searchHint.getPrimaryImageTag(), TvApp.getApplication().getApiClient()) :
Utils.isNonEmpty(searchHint.getThumbImageItemId()) ? ImageUtils.getImageUrl(searchHint.getThumbImageItemId(), ImageType.Thumb, searchHint.getThumbImageTag(), TvApp.getApplication().getApiClient()) : null;
if (Utils.isNonEmpty(searchHint.getPrimaryImageTag())) {
return ImageUtils.getImageUrl(searchHint.getItemId(), ImageType.Primary, searchHint.getPrimaryImageTag(), TvApp.getApplication().getApiClient());
} else if (Utils.isNonEmpty(searchHint.getThumbImageItemId())) {
return ImageUtils.getImageUrl(searchHint.getThumbImageItemId(), ImageType.Thumb, searchHint.getThumbImageTag(), TvApp.getApplication().getApiClient());
}
}
return null;
}
@@ -253,7 +301,9 @@ public class BaseRowItem {
public String getCardName() {
switch (type) {
case BaseItem:
if ("Audio".equals(baseItem.getType())) return baseItem.getAlbumArtist() != null ? baseItem.getAlbumArtist() : baseItem.getAlbum() != null ? baseItem.getAlbum() : "<Unknown>";
if ("Audio".equals(baseItem.getType())) {
return baseItem.getAlbumArtist() != null ? baseItem.getAlbumArtist() : baseItem.getAlbum() != null ? baseItem.getAlbum() : "<Unknown>";
}
default:
return getFullName();
}
@@ -291,7 +341,7 @@ public class BaseRowItem {
case BaseItem:
case LiveTvRecording:
case LiveTvProgram:
return "Audio".equals(baseItem.getType())? getFullName() : baseItem.getName();
return "Audio".equals(baseItem.getType()) ? getFullName() : baseItem.getName();
case Person:
return person.getName();
case Server:

View File

@@ -3,9 +3,11 @@ package org.jellyfin.androidtv.presentation;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import androidx.leanback.widget.BaseCardView;
import androidx.leanback.widget.Presenter;
import androidx.palette.graphics.Palette;
import android.view.View;
import android.view.ViewGroup;
@@ -92,12 +94,21 @@ public class CardPresenter extends Presenter {
BaseItemDto itemDto = mItem.getBaseItem();
boolean showWatched = true;
boolean showProgress = false;
double aspect = imageType.equals(ImageType.BANNER) ? ASPECT_RATIO_BANNER : imageType.equals(ImageType.THUMB) ? ImageUtils.ASPECT_RATIO_16_9 : Utils.getSafeValue(ImageUtils.getImageAspectRatio(itemDto, m.getPreferParentThumb()), ImageUtils.ASPECT_RATIO_7_9);
double aspect;
if (imageType.equals(ImageType.BANNER)) {
aspect = ASPECT_RATIO_BANNER;
} else if (imageType.equals(ImageType.THUMB)) {
aspect = ImageUtils.ASPECT_RATIO_16_9;
} else {
aspect = Utils.getSafeValue(ImageUtils.getImageAspectRatio(itemDto, m.getPreferParentThumb()), ImageUtils.ASPECT_RATIO_7_9);
}
switch (itemDto.getType()) {
case "Audio":
case "MusicAlbum":
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_audio);
if (aspect < 0.8) aspect = 1.0;
if (aspect < 0.8) {
aspect = 1.0;
}
showWatched = false;
break;
case "Person":
@@ -105,7 +116,9 @@ public class CardPresenter extends Presenter {
break;
case "MusicArtist":
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_port_person);
if (aspect <.8) aspect = 1.0;
if (aspect < .8) {
aspect = 1.0;
}
showWatched = false;
break;
case "RecordingGroup":
@@ -124,7 +137,7 @@ public class CardPresenter extends Presenter {
case Remote:
break;
case Virtual:
mCardView.setBanner((itemDto.getPremiereDate() != null ? TimeUtils.convertToLocalDate(itemDto.getPremiereDate()) : new Date(System.currentTimeMillis()+1)).getTime() > System.currentTimeMillis() ? R.drawable.banner_edge_future : R.drawable.banner_edge_missing);
mCardView.setBanner((itemDto.getPremiereDate() != null ? TimeUtils.convertToLocalDate(itemDto.getPremiereDate()) : new Date(System.currentTimeMillis() + 1)).getTime() > System.currentTimeMillis() ? R.drawable.banner_edge_future : R.drawable.banner_edge_missing);
break;
case Offline:
mCardView.setBanner(R.drawable.banner_edge_offline);
@@ -135,6 +148,10 @@ public class CardPresenter extends Presenter {
mCardView.setCardType(BaseCardView.CARD_TYPE_INFO_UNDER);
break;
case "CollectionFolder":
// Force the aspect ratio to 16x9 because the server is returning the wrong value of 1
aspect = ImageUtils.ASPECT_RATIO_16_9;
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_port_folder);
break;
case "Folder":
case "MovieGenreFolder":
case "MusicGenreFolder":
@@ -163,10 +180,16 @@ public class CardPresenter extends Presenter {
break;
}
cardHeight = !m.isStaticHeight() ? (aspect > 1 ? lHeight : pHeight) : sHeight;
cardWidth = (int)(aspect * cardHeight);
if (cardWidth < 10) cardWidth = 230; //Guard against zero size images causing picasso to barf
if (itemDto.getLocationType() == LocationType.Offline) mCardView.setBanner(R.drawable.banner_edge_offline);
if (itemDto.getIsPlaceHolder() != null && itemDto.getIsPlaceHolder()) mCardView.setBanner(R.drawable.banner_edge_disc);
cardWidth = (int) (aspect * cardHeight);
if (cardWidth < 10) {
cardWidth = 230; //Guard against zero size images causing picasso to barf
}
if (itemDto.getLocationType() == LocationType.Offline) {
mCardView.setBanner(R.drawable.banner_edge_offline);
}
if (itemDto.getIsPlaceHolder() != null && itemDto.getIsPlaceHolder()) {
mCardView.setBanner(R.drawable.banner_edge_disc);
}
UserItemDataDto userData = itemDto.getUserData();
if (showWatched && userData != null) {
if (userData.getPlayed()) {
@@ -176,8 +199,8 @@ public class CardPresenter extends Presenter {
}
}
if(showProgress && itemDto.getRunTimeTicks() != null && itemDto.getRunTimeTicks() > 0 && userData != null && userData.getPlaybackPositionTicks() > 0) {
mCardView.setProgress(((int)(userData.getPlaybackPositionTicks() * 100.0 / itemDto.getRunTimeTicks()))); // force floating pt math with 100.0
if (showProgress && itemDto.getRunTimeTicks() != null && itemDto.getRunTimeTicks() > 0 && userData != null && userData.getPlaybackPositionTicks() > 0) {
mCardView.setProgress(((int) (userData.getPlaybackPositionTicks() * 100.0 / itemDto.getRunTimeTicks()))); // force floating pt math with 100.0
} else {
mCardView.setProgress(0);
}
@@ -187,25 +210,36 @@ public class CardPresenter extends Presenter {
ChannelInfoDto channel = mItem.getChannelInfo();
double tvAspect = imageType.equals(ImageType.BANNER) ? ASPECT_RATIO_BANNER : imageType.equals(ImageType.THUMB) ? ImageUtils.ASPECT_RATIO_16_9 : Utils.getSafeValue(channel.getPrimaryImageAspectRatio(), ImageUtils.ASPECT_RATIO_7_9);
cardHeight = !m.isStaticHeight() ? tvAspect > 1 ? lHeight : pHeight : sHeight;
cardWidth = (int)((tvAspect) * cardHeight);
if (cardWidth < 10) cardWidth = 230; //Guard against zero size images causing picasso to barf
cardWidth = (int) ((tvAspect) * cardHeight);
if (cardWidth < 10) {
cardWidth = 230; //Guard against zero size images causing picasso to barf
}
mCardView.setMainImageDimensions(cardWidth, cardHeight);
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_port_tv);
break;
case LiveTvProgram:
BaseItemDto program = mItem.getProgramInfo();
Double programAspect = program.getPrimaryImageAspectRatio();
if (programAspect == null) programAspect = Utils.isTrue(program.getIsMovie()) ? ImageUtils.ASPECT_RATIO_2_3 : ImageUtils.ASPECT_RATIO_16_9;
if (Utils.isTrue(program.getIsMovie())) {
// The server reports the incorrect image aspect ratio for movies, so we are overriding it here
programAspect = ImageUtils.ASPECT_RATIO_2_3;
} else if (programAspect == null) {
programAspect = ImageUtils.ASPECT_RATIO_16_9;
}
cardHeight = !m.isStaticHeight() ? programAspect > 1 ? lHeight : pHeight : sHeight;
cardWidth = (int)((programAspect) * cardHeight);
if (cardWidth < 10) cardWidth = 230; //Guard against zero size images causing picasso to barf
cardWidth = (int) ((programAspect) * cardHeight);
if (cardWidth < 10) {
cardWidth = 230; //Guard against zero size images causing picasso to barf
}
switch (program.getLocationType()) {
case FileSystem:
case Remote:
case Offline:
break;
case Virtual:
if (program.getStartDate() != null && TimeUtils.convertToLocalDate(program.getStartDate()).getTime() > System.currentTimeMillis()) mCardView.setBanner(R.drawable.banner_edge_future);
if (program.getStartDate() != null && TimeUtils.convertToLocalDate(program.getStartDate()).getTime() > System.currentTimeMillis()) {
mCardView.setBanner(R.drawable.banner_edge_future);
}
break;
}
mCardView.setMainImageDimensions(cardWidth, cardHeight);
@@ -217,47 +251,49 @@ public class CardPresenter extends Presenter {
BaseItemDto recording = mItem.getRecordingInfo();
double recordingAspect = imageType.equals(ImageType.BANNER) ? ASPECT_RATIO_BANNER : (imageType.equals(ImageType.THUMB) ? ImageUtils.ASPECT_RATIO_16_9 : Utils.getSafeValue(recording.getPrimaryImageAspectRatio(), ImageUtils.ASPECT_RATIO_7_9));
cardHeight = !m.isStaticHeight() ? recordingAspect > 1 ? lHeight : pHeight : sHeight;
cardWidth = (int)((recordingAspect) * cardHeight);
if (cardWidth < 10) cardWidth = 230; //Guard against zero size images causing picasso to barf
cardWidth = (int) ((recordingAspect) * cardHeight);
if (cardWidth < 10) {
cardWidth = 230; //Guard against zero size images causing picasso to barf
}
mCardView.setMainImageDimensions(cardWidth, cardHeight);
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_port_tv);
break;
case Server:
cardWidth = (int)(ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
cardWidth = (int) (ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
mCardView.setMainImageDimensions(cardWidth, cardHeight);
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_port_server);
break;
case Person:
cardHeight = !m.isStaticHeight() ? pHeight : sHeight;
cardWidth = (int)(ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
cardWidth = (int) (ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
mCardView.setMainImageDimensions(cardWidth, cardHeight);
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_port_person);
break;
case User:
cardWidth = (int)(ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
cardWidth = (int) (ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
mCardView.setMainImageDimensions(cardWidth, cardHeight);
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_port_person);
break;
case Chapter:
cardHeight = !m.isStaticHeight() ? pHeight : sHeight;
cardWidth = (int)(ImageUtils.ASPECT_RATIO_16_9 * cardHeight);
cardWidth = (int) (ImageUtils.ASPECT_RATIO_16_9 * cardHeight);
mCardView.setMainImageDimensions(cardWidth, cardHeight);
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_chapter);
break;
case SearchHint:
switch (mItem.getSearchHint().getType()) {
case "Episode":
cardWidth = (int)(ImageUtils.ASPECT_RATIO_16_9 * cardHeight);
cardWidth = (int) (ImageUtils.ASPECT_RATIO_16_9 * cardHeight);
mCardView.setMainImageDimensions(cardWidth, cardHeight);
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_port_tv);
break;
case "Person":
cardWidth = (int)(ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
cardWidth = (int) (ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
mCardView.setMainImageDimensions(cardWidth, cardHeight);
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_port_person);
break;
default:
cardWidth = (int)(ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
cardWidth = (int) (ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
mCardView.setMainImageDimensions(cardWidth, cardHeight);
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_port_video);
break;
@@ -265,13 +301,13 @@ public class CardPresenter extends Presenter {
break;
case GridButton:
cardHeight = !m.isStaticHeight() ? pHeight : sHeight;
cardWidth = (int)(ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
cardWidth = (int) (ImageUtils.ASPECT_RATIO_7_9 * cardHeight);
mCardView.setMainImageDimensions(cardWidth, cardHeight);
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_port_video);
break;
case SeriesTimer:
cardHeight = !m.isStaticHeight() ? pHeight : sHeight;
cardWidth = (int)(ImageUtils.ASPECT_RATIO_16_9 * cardHeight);
cardWidth = (int) (ImageUtils.ASPECT_RATIO_16_9 * cardHeight);
mCardView.setMainImageDimensions(cardWidth, cardHeight);
mDefaultCardImage = TvApp.getApplication().getDrawableCompat(R.drawable.tile_land_series_timer);
//Always show info for timers
@@ -293,7 +329,9 @@ public class CardPresenter extends Presenter {
}
protected void updateCardViewImage(String url) {
if (!validContext()) return;
if (!validContext()) {
return;
}
try {
if (url == null) {
@@ -325,7 +363,9 @@ public class CardPresenter extends Presenter {
mCardView.clearBanner();
mCardView.setUnwatchedCount(-1);
mCardView.setProgress(0);
if (!validContext()) return;
if (!validContext()) {
return;
}
try {
Glide.with(getContext())
.load(TvApp.getApplication().getDrawable(R.drawable.loading))
@@ -351,16 +391,22 @@ public class CardPresenter extends Presenter {
@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
if (!(item instanceof BaseRowItem)) return;
if (!(item instanceof BaseRowItem)) {
return;
}
BaseRowItem rowItem = (BaseRowItem) item;
if (!rowItem.isValid()) return;
if (!rowItem.isValid()) {
return;
}
ViewHolder holder = (ViewHolder) viewHolder;
holder.setItem(rowItem, mImageType, 260, 300, mStaticHeight);
holder.mCardView.setTitleText(rowItem.getCardName());
holder.mCardView.setContentText(rowItem.getSubText());
if (ImageType.DEFAULT.equals(mImageType)) holder.mCardView.setOverlayInfo(rowItem);
if (ImageType.DEFAULT.equals(mImageType)) {
holder.mCardView.setOverlayInfo(rowItem);
}
holder.mCardView.showFavIcon(rowItem.isFavorite());
if (rowItem.isPlaying()) {
holder.mCardView.setPlayingIndicator(true);

View File

@@ -1,88 +1,90 @@
package org.jellyfin.androidtv.presentation;
import android.media.MediaPlayer;
import android.os.Handler;
import org.jellyfin.androidtv.R;
import org.jellyfin.androidtv.TvApp;
import org.jellyfin.androidtv.base.BaseActivity;
import org.jellyfin.androidtv.util.Utils;
import java.util.Calendar;
import java.util.GregorianCalendar;
/**
* Created by Eric on 10/24/2015.
*/
public class ThemeManager {
private static boolean isEnabled() {
return TvApp.getApplication().getPrefs().getBoolean("pref_enable_themes",true);
return TvApp.getApplication().getPrefs().getBoolean("pref_enable_themes", true);
}
private static boolean isHalloween() {
if (!isEnabled()) return false;
if (!isEnabled()) {
return false;
}
Calendar today = new GregorianCalendar();
return today.get(Calendar.MONTH) == 9 && (today.get(Calendar.DAY_OF_MONTH) == 30 || today.get(Calendar.DAY_OF_MONTH) == 31);
return today.get(Calendar.MONTH) == Calendar.OCTOBER &&
(today.get(Calendar.DAY_OF_MONTH) == 30 || today.get(Calendar.DAY_OF_MONTH) == 31);
}
private static boolean isHolidays() {
if (!isEnabled()) return false;
if (!isEnabled()) {
return false;
}
Calendar today = new GregorianCalendar();
return today.get(Calendar.MONTH) == 11 && (today.get(Calendar.DAY_OF_MONTH) > 20 && today.get(Calendar.DAY_OF_MONTH) < 27);
return today.get(Calendar.MONTH) == Calendar.DECEMBER &&
(today.get(Calendar.DAY_OF_MONTH) > 20 && today.get(Calendar.DAY_OF_MONTH) < 27);
}
public static int getBrandColor() {
return isHalloween() ?
TvApp.getApplication().getResources().getColor(R.color.halloween_end) :
isHolidays() ?
TvApp.getApplication().getResources().getColor(R.color.holiday_end) :
Utils.getBrandColor();
private static void showHolidayMessage(final BaseActivity activity, final String title, final String message, final Integer icon, final Integer background) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// make sure they haven't moved away from that activity
if (TvApp.getApplication().getCurrentActivity() == null ||
TvApp.getApplication().getCurrentActivity() != activity) {
return;
}
activity.showMessage(title, message, 10000, icon, background);
}
}, 2000);
}
public static void showWelcomeMessage() {
final BaseActivity currentActivity = TvApp.getApplication().getCurrentActivity();
if (isHalloween() && currentActivity != null) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// make sure they haven't moved away from that activity
if (TvApp.getApplication().getCurrentActivity() == null || TvApp.getApplication().getCurrentActivity() != currentActivity) return;
MediaPlayer mp = MediaPlayer.create(TvApp.getApplication(), R.raw.howl);
mp.start();
currentActivity.showMessage("Happy Halloween!", "Try some of our spooky suggestions", 10000, R.drawable.ic_ghost, R.drawable.orange_gradient);
}
}, 2000);
} else
if (isHolidays() && currentActivity != null) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// make sure they haven't moved away from that activity
if (TvApp.getApplication().getCurrentActivity() == null || TvApp.getApplication().getCurrentActivity() != currentActivity) return;
MediaPlayer mp = MediaPlayer.create(TvApp.getApplication(), R.raw.sleighbells);
mp.start();
currentActivity.showMessage("Happy Holidays!", "Try some of our holiday suggestions", 10000, R.drawable.ic_snowflake, R.drawable.holiday_gradient);
}
}, 2000);
if (currentActivity != null) {
if (isHalloween()) {
showHolidayMessage(currentActivity,
currentActivity.getString(R.string.title_suggestions_halloween),
currentActivity.getString(R.string.desc_suggestions_halloween),
R.drawable.ic_ghost,
R.drawable.orange_gradient);
} else if (isHolidays()) {
showHolidayMessage(currentActivity,
currentActivity.getString(R.string.title_suggestions_holiday),
currentActivity.getString(R.string.desc_suggestions_holiday),
R.drawable.ic_snowflake,
R.drawable.holiday_gradient);
}
}
}
public static String[] getSpecialGenres() {
if (isHalloween()) {
return new String[] {"Halloween","Horror"};
return new String[]{"Halloween", "Horror"};
}
if (isHolidays()) {
return new String[] {"Holiday","Holidays","Christmas"};
return new String[]{"Holiday", "Holidays", "Christmas"};
}
return null;
}
public static String getSuggestionTitle() {
return isHalloween() ? "Spooky Suggestions" : isHolidays() ? "Holiday Suggestions" : "Suggestions";
int labelId = R.string.lbl_suggestions;
if (isHalloween()) {
labelId = R.string.lbl_suggestions_halloween;
} else if (isHolidays()) {
labelId = R.string.lbl_suggestions_holiday;
}
return TvApp.getApplication().getCurrentActivity().getString(labelId);
}
}

View File

@@ -12,5 +12,20 @@ public enum QueryType {
StaticChapters,
StaticServers,
Users,
Search, Specials, Trailers, LiveTvChannel, LiveTvProgram, LiveTvRecording, LiveTvRecordingGroup, StaticItems, Persons, StaticAudioQueueItems, AlbumArtists, AudioPlaylists, ContinueWatching, LatestItems, SeriesTimer, Premieres
Search,
Specials,
Trailers,
LiveTvChannel,
LiveTvProgram,
LiveTvRecording,
LiveTvRecordingGroup,
StaticItems,
Persons,
StaticAudioQueueItems,
AlbumArtists,
AudioPlaylists,
ContinueWatching,
LatestItems,
SeriesTimer,
Premieres
}

View File

@@ -181,7 +181,8 @@ public class StartupActivity extends Activity {
}
// Check the server version
if (!AuthenticationHelper.isSupportedServerVersion(response.getServers().get(0))) {
if (!response.getServers().isEmpty() &&
!AuthenticationHelper.isSupportedServerVersion(response.getServers().get(0))) {
Utils.showToast(activity, activity.getString(R.string.msg_error_server_version, TvApp.MINIMUM_SERVER_VERSION));
AuthenticationHelper.automaticSignIn(connectionManager, activity);
return;

View File

@@ -4,28 +4,31 @@ import android.app.ProgressDialog;
import android.content.Context;
import android.os.Handler;
import androidx.annotation.NonNull;
import org.jellyfin.androidtv.R;
import org.jellyfin.androidtv.TvApp;
/**
* Created by Eric on 12/28/2014.
*/
public class DelayedMessage {
private String title = TvApp.getApplication().getString(R.string.lbl_please_wait);
private String message = TvApp.getApplication().getString(R.string.msg_little_longer);
private Runnable runnable;
private final String title;
private final String message;
private final Handler handler;
private final Runnable runnable;
private ProgressDialog dialog;
private Handler handler;
public DelayedMessage(final Context activity) {
public DelayedMessage(@NonNull final Context activity) {
this(activity, 750);
}
public DelayedMessage(final Context activity, int delay) {
handler = new Handler();
public DelayedMessage(@NonNull final Context activity, int delay) {
title = TvApp.getApplication().getString(R.string.lbl_please_wait);
message = TvApp.getApplication().getString(R.string.msg_little_longer);
handler = new Handler(activity.getMainLooper());
runnable = new Runnable() {
@Override
public void run() {
if (activity != null) dialog = ProgressDialog.show(activity, title, message);
dialog = ProgressDialog.show(activity, title, message);
}
};
handler.postDelayed(runnable, delay);
@@ -33,6 +36,8 @@ public class DelayedMessage {
public void Cancel() {
handler.removeCallbacks(runnable);
if (dialog != null) dialog.dismiss();
if (dialog != null) {
dialog.dismiss();
}
}
}

View File

@@ -195,6 +195,9 @@ public class ImageUtils {
if (item.getType().equals("Season") && imageTag == null) {
imageTag = item.getSeriesPrimaryImageTag();
itemId = item.getSeriesId();
} else if (item.getType().equals("Program") && item.getHasThumb()) {
imageTag = item.getImageTags().get(ImageType.Thumb);
imageType = ImageType.Thumb;
}
}

View File

@@ -90,15 +90,16 @@ public class AuthenticationHelper {
private static Response<ConnectionResult> getSignInResponse(final Activity activity, final String address) {
// This is taking longer than expected message
// final DelayedMessage message = new DelayedMessage(activity);
final DelayedMessage message = new DelayedMessage(activity);
return new Response<ConnectionResult>() {
@Override
public void onResponse(ConnectionResult serverResult) {
// message.Cancel();
message.Cancel();
// Check the server version
if (!isSupportedServerVersion(serverResult.getServers().get(0))) {
if (!serverResult.getServers().isEmpty() &&
!isSupportedServerVersion(serverResult.getServers().get(0))) {
Utils.showToast(activity, activity.getString(R.string.msg_error_server_version, TvApp.MINIMUM_SERVER_VERSION));
return;
}
@@ -124,7 +125,7 @@ public class AuthenticationHelper {
@Override
public void onError(Exception exception) {
// message.Cancel();
message.Cancel();
TvApp.getApplication().getLogger().ErrorException("Error trying to sign in to specific server " + address, exception);
Utils.showToast(activity, activity.getString(R.string.msg_error_connecting_server));
}

Binary file not shown.

Binary file not shown.

View File

@@ -2,14 +2,14 @@
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="error">Erreur</string>
<string name="ok">OK</string>
<string name="video_error_unknown_error">Echec de chargement de la vidéo</string>
<string name="txt_loading">Chargement...</string>
<string name="video_error_unknown_error">Échec de chargement de la vidéo</string>
<string name="txt_loading">Chargement</string>
<string name="title_activity_select_user">Sélection du compte utilisateur</string>
<string name="home_title">Accueil</string>
<string name="btn_cancel">Annuler</string>
<string name="byletter_letters">ABCDEFGHIJKLMNOPQRSTUVWXYZ</string>
<string name="pref_login_behavior_title">Démarrage</string>
<string name="pref_show_login">Ecran de login</string>
<string name="pref_show_login">Ecran de connexion</string>
<string name="pref_playback">Lecture</string>
<string name="pref_max_bitrate_title">Débit max de streaming</string>
<string name="pref_auto_login">Se connecter automatiquement avec cet utilisateur</string>
@@ -25,7 +25,7 @@
<string name="pref_auto_logoff_title">Timeout de déconnexion automatique</string>
<string name="pref_general">Général</string>
<string name="lbl_settings">Paramètres</string>
<string name="lbl_logout">"Déconnexion "</string>
<string name="lbl_logout">Déconnexion</string>
<string name="lbl_send_logs">Envoyer les journaux d\'événements</string>
<string name="lbl_library">Bibliothèque</string>
<string name="lbl_continue_watching">Continuer la lecture</string>
@@ -51,7 +51,7 @@
<string name="lbl_tv_series">Séries TV</string>
<string name="lbl_other">Autre</string>
<string name="lbl_latest_additions">Derniers ajouts</string>
<string name="lbl_because_you_watched">"Parce que vous avez regardé"</string>
<string name="lbl_because_you_watched">"Parce que vous avez regardé "</string>
<string name="lbl_play_all">Lire tout</string>
<string name="lbl_shuffle_all">Lecture aléatoire</string>
<string name="lbl_play">Lecture</string>
@@ -66,10 +66,10 @@
<string name="msg_unable_to_cancel">Impossible d\'annuler l\'enregistrement</string>
<string name="lbl_cast_crew">Distribution et équipe</string>
<string name="lbl_chapters">Chapitres</string>
<string name="lbl_specials">Episodes spéciaux</string>
<string name="lbl_specials">Épisodes spéciaux</string>
<string name="lbl_trailers">Bandes-annonces</string>
<string name="lbl_items">Eléments</string>
<string name="lbl_item">Elément</string>
<string name="lbl_item">Élément</string>
<string name="lbl_seasons">Saisons</string>
<string name="lbl_upcoming">A venir</string>
<string name="lbl_sd">SD</string>
@@ -77,14 +77,14 @@
<string name="lbl_min">" min "</string>
<string name="lbl_ends">"Fin :"</string>
<string name="lbl_directed_by">"Réalisé par :"</string>
<string name="lbl_last_played">"Dernière lecture"</string>
<string name="lbl_last_played">"Dernière lecture "</string>
<string name="lbl_select_server">Sélectionnez un serveur</string>
<string name="lbl_other_options">Autres options</string>
<string name="lbl_enter_manually">Entrez manuellement</string>
<string name="lbl_select_user">Sélectionnez un utilisateur</string>
<string name="lbl_paren_login_as">"(se connecter en tant que"</string>
<string name="lbl_to_change_paren">"pour changer)"</string>
<string name="lbl_login_as">"Se connecter en tant que"</string>
<string name="lbl_paren_login_as">" (se connecter en tant que "</string>
<string name="lbl_to_change_paren">" pour changer)"</string>
<string name="lbl_login_as">"Se connecter en tant que "</string>
<string name="lbl_tv">TV</string>
<string name="lbl_people">Personnes</string>
<string name="lbl_videos">Vidéos</string>
@@ -307,4 +307,15 @@
<string name="pref_use_external_player_summary">Nécessite une application capable de lire les vidéos</string>
<string name="pref_use_direct_path_title">Utiliser le chemin directe</string>
<string name="pref_use_direct_path_summary">Utiliser le chemin du fichier de l\'url de streaming</string>
</resources>
<string name="lbl_now_playing_album">de %s</string>
<string name="lbl_watched">Vu</string>
<string name="msg_error_server_version">La version du serveur n\'est pas supporté. La version du serveur dois être %1$s ou ultérieur.</string>
<string name="pref_external_live_tv_summary">Requiert une application capable de lire des flux en directe</string>
<string name="pref_external_live_tv_title">Utiliser un Lecteur Externe pour la TV en Directe</string>
<string name="lbl_warning">Attention</string>
<string name="lbl_now_playing_track">%s de %s</string>
<string name="msg_error_signin">Il y a eu une erreur de connexion avec les identifiants enregistrés.</string>
<string name="msg_error_server_unavailable">Serveur indisponible</string>
<string name="lbl_status">%s / %s</string>
<string name="pref_authentication_cat">Identification</string>
</resources>

View File

@@ -0,0 +1,325 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_name" translatable="false">Jellyfin</string>
<string name="error">Алдаа</string>
<string name="ok">Ok</string>
<string name="play">Тоглуулах</string>
<string name="video_error_unknown_error">Бичлэг алдаатай</string>
<string name="loading">Ачааллаж байна…</string>
<string name="txt_loading">Ачааллаж байна..</string>
<string name="title_activity_select_user">Идэвхитэй хэрэглэгч сонго</string>
<string name="home_title">Нүүр</string>
<string name="btn_cancel">Цуцлах</string>
<string name="byletter_letters">ABCDEFGHIJKLMNOPQRSTUVWXYZ</string>
<string name="pref_login_behavior_title">Эхлэх байдал</string>
<string name="pref_show_login">Нэвтрэх дэлгэцийг харуулах</string>
<string name="pref_playback">Тоглуулах</string>
<string name="pref_max_bitrate_title">Хамгийн их цацалт Bitrate</string>
<string name="pref_auto_login">Энэ хэрэглэгчээр автоматаар нэвтрэх</string>
<string name="settings_title">Тохиргоо</string>
<string name="pref_authentication_cat">Гэрчлэлт</string>
<string name="pref_prompt_pw">Нууц үгийн сануулга</string>
<string name="pref_alt_pw_entry">Хэрэглэгчийн D-Pad нууц үг оруулах</string>
<string name="pref_alt_pw_entry_desc">Зөвхөн D-Pad товчлууруудыг ашиглан тоон нууц үг оруулах</string>
<string name="title_activity_dpad_pw">Нууц үгээ оруулна уу</string>
<string name="enter_password">Нууц үгээ оруулна уу</string>
<string name="dpad_entry_desc">Алсын удирдлага дээрх D-Pad-ыг ашиглан тоон нууц үг оруулна уу. Эхний жагсаалтад байгаа дугаарын товчлуур дээр эсвэл давхар дарж хоёрыг аваарай. Жишээ нь нэгийг дарахын тулд \"дээш\", 5-ыг сонгохын тулд хоёр удаа дарна уу. 1 секундын турш бариад дууссаны дараа \'сонгох\' товчийг, эсвэл зүүн товчийг дарж дахин эхлүүлнэ үү.</string>
<string name="dpad_pw_cancel">* \'Доош\' товчийг 1 секундын турш бариад альфа нууц үгтэй эсвэл нэвтрэхэд шаардлагатай бол гаргана уу</string>
<string name="chapters">Тэмдэгтүүд</string>
<string name="pref_auto_logoff_title">Автоматаар гарах хугацаа</string>
<string name="pref_general">Ерөнхий</string>
<string name="lbl_settings">Тохиргоо</string>
<string name="lbl_logout">Гарах</string>
<string name="lbl_send_logs">Мэдээлэл илгээх</string>
<string name="lbl_library">Сан</string>
<string name="lbl_continue_watching">Үргэлжлүүлэн үзэх</string>
<string name="lbl_latest_movies">Хамгийн сүүлийн үеийн кинонууд</string>
<string name="lbl_next_up">Дараах</string>
<string name="lbl_next_up_tv">Дараагийн ТВ</string>
<string name="lbl_on_now">Одоо асаах</string>
<string name="lbl_views">Үзсэн</string>
<string name="lbl_by_letter">Дараагийн үсэг</string>
<string name="lbl_suggested">Санал болгож буй</string>
<string name="lbl_status"/>
<string name="lbl_genres">Төрөл зүйл</string>
<string name="lbl_performers">Гүйцэтгэгчид</string>
<string name="lbl_search">Хайх</string>
<string name="msg_not_implemented">" хэрэгжүүлээгүй байна"</string>
<string name="lbl_latest">Сүүлийн үеийн</string>
<string name="lbl_by_name">Нэрээр нь</string>
<string name="lbl_favorites">Дуртай</string>
<string name="lbl_coming_up">Дээшээ ирж байна</string>
<string name="lbl_favorite_channels">Дуртай суваг</string>
<string name="lbl_other_channels">Бусад суваг</string>
<string name="lbl_collections">Багц</string>
<string name="lbl_movies">Кино</string>
<string name="lbl_tv_series">ТВ шоу</string>
<string name="lbl_other">Бусад</string>
<string name="lbl_latest_additions">Сүүлд нэмэгдсэн</string>
<string name="lbl_because_you_watched">"Та үзсэн болохоор "</string>
<string name="lbl_play_all">Бүгдийг тоглуулах</string>
<string name="lbl_shuffle_all">Бүгдийг хутгах</string>
<string name="lbl_play">Тоглуулах</string>
<string name="lbl_cancel">Цуцлах</string>
<string name="lbl_cancel_recording">Бичлэгийг цуцлах</string>
<string name="lbl_cancel_series">Цувралыг цуцлах</string>
<string name="lbl_record_series">Цувралыг бичих</string>
<string name="lbl_record">Бичлэг</string>
<string name="msg_set_to_record">Хөтөлбөрийг бичлэг хийхээр тохируулсан</string>
<string name="msg_unable_to_create_recording">Бичлэг хийх боломжгүй</string>
<string name="msg_recording_cancelled">Бичлэгийг цуцаллаа</string>
<string name="msg_unable_to_cancel">Бичлэгийг цуцлах боломжгүй байна</string>
<string name="lbl_cast_crew"/>
<string name="lbl_chapters">Тэмдэгтүүд</string>
<string name="lbl_specials">Онцгой</string>
<string name="lbl_trailers"/>
<string name="lbl_items"/>
<string name="lbl_item">нэгж</string>
<string name="lbl_series">цуврал</string>
<string name="lbl_seasons">Үе</string>
<string name="lbl_upcoming">Удахгүй болох гэж байна</string>
<string name="lbl_favorite">Дуртай</string>
<string name="lbl_watched">Үзсэн</string>
<string name="lbl_sd"/>
<string name="lbl_runs">Ажиллуулах</string>
<string name="lbl_min"/>
<string name="lbl_ends">Дуусах</string>
<string name="lbl_directed_by">Найруулсан</string>
<string name="lbl_last_played">"Хамгийн сүүлд тоглосон "</string>
<string name="lbl_select_server">Сервер сонгох</string>
<string name="lbl_other_options">Бусад сонголтууд</string>
<string name="lbl_enter_manually">Гараар оруулна уу</string>
<string name="lbl_select_user">Хэрэглэгчийг сонгоно уу</string>
<string name="lbl_paren_login_as">" (нэвтрэх "</string>
<string name="lbl_to_change_paren">" сонгогдсон)"</string>
<string name="lbl_login_as">"Нэвтрэх "</string>
<string name="lbl_tv">ТВ</string>
<string name="lbl_people">Хүмүүс</string>
<string name="lbl_videos">Видеонууд</string>
<string name="lbl_recordings">Бичлэгүүд</string>
<string name="lbl_none">Аль нь ч биш</string>
<string name="msg_video_playback_error">"Видео дахин тоглуулахад алдаатай - "</string>
<string name="lbl_bracket_unknown">&lt;Тодорхойгүй&gt;</string>
<string name="msg_access_restricted">Энэ удаа хандалтыг хязгаарласан байна</string>
<string name="lbl_trailer">"Трейлер "</string>
<string name="lbl_play_trailers">трейлер үзэх</string>
<string name="lbl_please_wait">Түр хүлээнэ үү</string>
<string name="lbl_enter_user_name">Хрээглэгчийн нэр оруулна уу</string>
<string name="lbl_enter_user_pw">Нууц үгээ оруулна уу</string>
<string name="msg_little_longer">Энэ нь бодож байснаас удаж байна ...</string>
<string name="msg_report_sent">Мэдэгдэл хөгжүүлэгч рүү илгээсэн. Баярлалаа.</string>
<string name="lbl_report_msg_question">Хөгжүүлэгч рүү алдааны мэдэгдэл илгээх үү\?</string>
<string name="lbl_no">Үгүй</string>
<string name="msg_report_not_sent">Мэдэгдэл илгээгдсэнгүй</string>
<string name="lbl_yes">Тийм</string>
<string name="msg_error_connecting_server">Сервертэй холбогдоход алдаа гарлаа.</string>
<string name="msg_error_server_unavailable">Сервер тодорхойгүй</string>
<string name="msg_error_server_version">Дэмжигдээгүй серверийн хувилбар. Серверийн хувилбар% 1 $ s буюу түүнээс дээш байх шаардлагатай.</string>
<string name="msg_error_signin">Хадгалсан мэдээлэлтэйгээ нэвтрэх үед алдаа гарлаа.</string>
<string name="msg_invalid_id_pw">Хэрэглэгчийн ID эсвэл нууц үг буруу байна</string>
<string name="lbl_version">"Хувилбар "</string>
<string name="lbl_ip_hint"/>
<string name="lbl_enter_server_address">Серверийн хаяг оруулна уу</string>
<string name="lbl_valid_server_address">Серверийн хаягийг оруулна уу (IP эсвэл домэйн / нэр)</string>
<string name="lbl_ok"/>
<string name="lbl_born">"Эхэлсэн "</string>
<string name="lbl_loading_elipses">Дуудаж байна...</string>
<string name="msg_playback_not_allowed">Яг одоогоор тоглуулах боломжгүй байна</string>
<string name="msg_playback_restricted">Админ одоогоор энэ зүйлийг дахин тоглуулахыг хязгаарласан байна</string>
<string name="msg_playback_incompatible">Энэ видео форматыг тоглуулах боломжгүй байна</string>
<string name="lbl_never">Боломжгүй</string>
<string name="msg_cannot_play_time">Яг одоо энэ зүйлийг тоглуулах боломжгүй байна</string>
<string name="msg_cannot_play">Энэ зүйлийг тоглуулж чадахгүй байна</string>
<string name="lbl_no_items">Байхгүй байна</string>
<string name="lbl_empty">Хоосон</string>
<string name="lbl_tv_queuing">Дараачийн бүх ангийг дараалалд оруулах</string>
<string name="sum_tv_queuing">Бүлэг тоглож байхдаа улирлын үлдсэн хэсгийг дараалалд нэмж оруулаарай</string>
<string name="lbl_search_hint">Текст хайх (гарнаас сонгох)</string>
<string name="lbl_play_first_unwatched">Эхлээд тоглогдоогүйг тоглуул</string>
<string name="lbl_confirm_mark_watched">Энэ нь бүх агуулгыг тоглогдсон гэж тэмдэглэнэ. Та итгэлтэй байна уу\?</string>
<string name="lbl_mark_unplayed">Тоглогдоогүй гэж тэмдэглэ</string>
<string name="lbl_mark_played">Тоглосон гэж тэмдэглэсэн</string>
<string name="lbl_remove_favorite">Дуртай зүйлийг устгана уу</string>
<string name="lbl_add_favorite">Дуртай зүйл нэмэх</string>
<string name="lbl_now_playing_track"/>
<string name="lbl_now_playing_album">- %s</string>
<string name="lbl_like"/>
<string name="lbl_dislike"/>
<string name="lbl_unlike"/>
<string name="lbl_remove_dislike"/>
<string name="lbl_confirm_mark_unwatched">Энэ нь бүх агуулгыг тоглуулаагүй гэж тэмдэглэнэ. Та итгэлтэй байна уу\?</string>
<string name="msg_no_playable_items">Тоглуулах боломжтой зүйл байхгүй байна</string>
<string name="lbl_unwatched">Саналгүй</string>
<string name="lbl_load_channels">"Сувгуудыг ачаалах "</string>
<string name="lbl_today">Өнөөдөр</string>
<string name="lbl_tomorrow">Маргааш</string>
<string name="lbl_on">Асаалттай байна</string>
<string name="lbl_tune_to_channel">Суваг тааруулах</string>
<string name="msg_recording_now">Одоо бичлэг хийж байна</string>
<string name="msg_will_record">Бичлэг хийнэ</string>
<string name="lbl_begin_padding"/>
<string name="lbl_program_ended">Хөтөлбөр дуусав</string>
<string name="lbl_end_padding"/>
<string name="lbl_similar_items_library"/>
<string name="lbl_record_any_channel">Аль ч суваг дээр бичлэг хийх</string>
<string name="lbl_record_any_time">Ямар ч үед бичлэг хийх</string>
<string name="lbl_only_new_episodes">Зөвхөн шинэ ангиуд</string>
<string name="lbl_repeat_options">Сонголтуудыг давтана уу</string>
<string name="msg_cancel_entire_series"/>
<string name="msg_remote_already_playing">Алсаас тоглуулах хүсэлтийг хэрэгсэхгүй болгосон байна. Эхлээд одоогийн зүйлийг зогсооно уу.</string>
<string name="pref_audio_direct">Зам</string>
<string name="pref_audio_compat"/>
<string name="lbl_audio_output">Дууны гаралт</string>
<string name="lbl_goto_series">Цуврал уруу шилжих</string>
<string name="lbl_select_color">Өнгө сонгох</string>
<string name="lbl_sideline_color">Хажуугийн өнгө</string>
<string name="desc_sideline_color">Ангилалын хажуугийн самбарын өнгө</string>
<string name="lbl_show_info_panel">Мэдээллийн самбарыг харуул</string>
<string name="lbl_enable_debug">Сонголтуудын тохиргоо</string>
<string name="desc_info_panel">Дэлгэцийн хувьд одоо байгаа зүйлийн талаар дэлгэрэнгүй мэдээлэлгүйгээр самбарыг харуул</string>
<string name="desc_debug">Тохируулга хийх талаар нэмэлт мэдээлэл өгнө үү</string>
<string name="lbl_showing">Үзүүлж байна</string>
<string name="lbl_all_items">Бүх зүйлс</string>
<string name="lbl_sorted_by">эрэмбэлсэн</string>
<string name="lbl_from">-аас</string>
<string name="lbl_name">Нэр</string>
<string name="lbl_date_added">Өдөр нэмэх</string>
<string name="lbl_premier_date"/>
<string name="lbl_critic_rating">Зэрэглэл</string>
<string name="lbl_rating">Зэрэглэл</string>
<string name="lbl_starting_with">тэднээс нэрнээс эхэлнэ</string>
<string name="btn_done">Дуусгах</string>
<string name="lbl_display_preferences">Харуулах тохиргоог хийх</string>
<string name="lbl_season">Улирал</string>
<string name="lbl__continuing">ХОЛБООТОЙ</string>
<string name="lbl_ended">ДУУССАН</string>
<string name="btn_start_now">Яг одоо эхлэх</string>
<string name="btn_stop">Зогс</string>
<string name="btn_filter">Шүүлтүүр</string>
<string name="btn_clear_all">Бүгдийг арилгах</string>
<string name="lbl_filters">Шүүлтүүрүүд</string>
<string name="msg_subtitles_loading">Хадмалуудыг ачаалж байна ...</string>
<string name="msg_unable_load_subs">Хадмал орчуулгыг ачаалах боломжгүй байна</string>
<string name="msg_burn_sub_warning"/>
<string name="lbl_recording">Бичлэг хийж байна</string>
<string name="lbl_no_recordings">Ямар ч бичлэг байхгүй байна</string>
<string name="lbl_live_tv_guide">Хөтөлбөр</string>
<string name="lbl_recorded_tv">Бичигдсэн ТВ</string>
<string name="btn_ok"/>
<string name="pref_live_tv_cat"/>
<string name="msg_error_live_stream">Шууд ТВ цацахад алдаа гарлаа. Дахин оролдоно уу ...</string>
<string name="lbl_direct_stream_live">Шууд дамжуулалт шууд ТВ</string>
<string name="lbl_programs"/>
<string name="lbl_albums">Цомог</string>
<string name="lbl_artists">Жүжигчин</string>
<string name="lbl_song">Дуу</string>
<string name="lbl_songs">Дуунууд</string>
<string name="lbl_album">Цомог</string>
<string name="lbl_episodes">Бүлгүүд</string>
<string name="lbl_enable_cinema_mode"/>
<string name="sum_enable_cinema_mode">Сервер идэвхжүүлсэн үед киног тоглуулж эхлэхээс өмнө танилцуулга болон урьдчилан танилцуулгыг үзүүлэх</string>
<string name="lbl_playlists">Тоглуулах жагсаалт</string>
<string name="lbl_warning">Анхааруулга</string>
<string name="lbl_of">-</string>
<string name="msg_added_item_to_queue">"Энэ зүйлийг байрлалд дараалалд нэмсэн "</string>
<string name="msg_items_added">" зүйлийг нэмсэн"</string>
<string name="msg_total_items_in_queue">" дараалалд байгаа нийт зүйлс"</string>
<string name="lbl_add_to_queue">Дараалалд нэмэх</string>
<string name="lbl_open_artist">Чөлөөт уран бүтээлч</string>
<string name="lbl_open_album">Цомог нээх</string>
<string name="lbl_reshuffle_queue">Дахин дарааллыг дахин хийх</string>
<string name="lbl_next_item">Дараах</string>
<string name="lbl_prev_item">Өмнөх</string>
<string name="lbl_shuffle"/>
<string name="msg_reshuffle_audio_queue">Одоогийн аудио дарааллыг дахин асаах уу\?</string>
<string name="lbl_up_next_colon">"Дараа нь: "</string>
<string name="lbl_now_playing">Одоо тоглож байгаа</string>
<string name="lbl_play_from_here">Эндээс тоглоорой</string>
<string name="lbl_remove_from_queue">Дарааллаас хасах</string>
<string name="lbl_goto_now_playing">Одоо тоглох дээр оч</string>
<string name="lbl_instant_mix">Шуурхай холимог</string>
<string name="lbl_save_as_playlist"/>
<string name="lbl_delete"/>
<string name="msg_item_added"/>
<string name="btn_replace_queue"/>
<string name="lbl_items_in_queue"/>
<string name="msg_replace_or_add_queue_q"/>
<string name="lbl_enable_seasonal_themes"/>
<string name="desc_seasonal_themes"/>
<string name="desc_automatic_fav_songs"/>
<string name="lbl_switch_server"/>
<string name="lbl_forget"/>
<string name="lbl_new_premieres"/>
<string name="lbl_bitstream_ac3"/>
<string name="desc_bitstream_ac3"/>
<string name="lbl_normal"/>
<string name="lbl_zoom"/>
<string name="lbl_horizontal_stretch"/>
<string name="lbl_vertical_stretch"/>
<string name="lbl_audio_capabilitites"/>
<string name="msg_audio_warning"/>
<string name="msg_external_path"/>
<string name="btn_got_it"/>
<string name="btn_set_compatible_audio"/>
<string name="lbl_current_queue"/>
<string name="desc_current_video_queue"/>
<string name="lbl_clear_queue"/>
<string name="lbl_play_next_up"/>
<string name="lbl_open"/>
<string name="lbl_show_backdrop"/>
<string name="lbl_use_vlc_livetv"/>
<string name="desc_use_vlc_livetv"/>
<string name="lbl_refresh_switching"/>
<string name="lbl_show_premieres"/>
<string name="desc_premieres"/>
<string name="lbl_bitstream_dts"/>
<string name="lbl_in_x_days"/>
<string name="lbl_select_date"/>
<string name="pref_live_tv_mode"/>
<string name="pref_live_tv_mode_desc"/>
<string name="lbl_just_this_once"/>
<string name="msg_record_entire_series"/>
<string name="no_program_data"/>
<string name="lbl_sports"/>
<string name="lbl_kids"/>
<string name="lbl_recent_recordings"/>
<string name="lbl_all_recordings"/>
<string name="lbl_repeat"/>
<string name="lbl_new"/>
<string name="lbl_live"/>
<string name="lbl_schedule"/>
<string name="lbl_episode_not_record"/>
<string name="lbl_series_settings"/>
<string name="msg_settings_updated"/>
<string name="lbl_save"/>
<string name="lbl_series_recordings"/>
<string name="lbl_any_channel"/>
<string name="lbl_all_episodes"/>
<string name="lbl_at_any_time"/>
<string name="lbl_seconds"/>
<string name="lbl_minutes"/>
<string name="lbl_hour"/>
<string name="lbl_minute"/>
<string name="lbl_hours"/>
<string name="lbl_on_schedule"/>
<string name="title_activity_expanded_text"/>
<string name="lbl_guest_stars"/>
<string name="lbl_premiere"/>
<string name="lbl_sort_by"/>
<string name="lbl_show_indicators"/>
<string name="lbl_guide_option_played"/>
<string name="lbl_guide_option_number"/>
<string name="lbl_resume_preroll"/>
<string name="lbl_resume_from"/>
<string name="lbl_more_like_this"/>
<string name="lbl_previous_episode"/>
<string name="lbl_next_episode"/>
<string name="lbl_album_name"/>
<string name="lbl_song_title"/>
<string name="pref_use_external_player_title"/>
<string name="pref_use_external_player_summary"/>
<string name="pref_external_live_tv_title"/>
<string name="pref_external_live_tv_summary"/>
<string name="pref_use_direct_path_title"/>
<string name="pref_use_direct_path_summary"/>
</resources>

View File

@@ -322,4 +322,11 @@
<string name="pref_external_live_tv_summary">Requires a capable app to play live streams</string>
<string name="pref_use_direct_path_title">Pass Direct Path</string>
<string name="pref_use_direct_path_summary">Pass the file system path instead of streaming URL</string>
<string name="lbl_suggestions">Suggestions</string>
<string name="lbl_suggestions_halloween">Spooky Suggestions</string>
<string name="title_suggestions_halloween">Happy Halloween!</string>
<string name="desc_suggestions_halloween">Try some of our spooky suggestions</string>
<string name="lbl_suggestions_holiday">Holiday Suggestions</string>
<string name="title_suggestions_holiday">Happy Holidays!</string>
<string name="desc_suggestions_holiday">Try some of our holiday suggestions</string>
</resources>