Add UnreachableActivity for when the server cannot be reached.

This commit is contained in:
天クマ 2026-01-23 16:04:27 -03:00
commit 34c4bcc831
28 changed files with 279 additions and 39 deletions

View file

@ -66,7 +66,7 @@
android:name="org.adrianvictor.geleia.views.shortcuts.AppShortcutLauncherActivity" android:name="org.adrianvictor.geleia.views.shortcuts.AppShortcutLauncherActivity"
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:theme="@android:style/Theme.Translucent.NoTitleBar" /> android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<activity android:name="org.adrianvictor.geleia.activities.UnreachableActivity" />
<service android:name="org.adrianvictor.geleia.service.DownloadService" /> <service android:name="org.adrianvictor.geleia.service.DownloadService" />
<service android:name="org.adrianvictor.geleia.service.LoginService" /> <service android:name="org.adrianvictor.geleia.service.LoginService" />
<service android:name="org.adrianvictor.geleia.service.MusicService" /> <service android:name="org.adrianvictor.geleia.service.MusicService" />

View file

@ -40,7 +40,7 @@ public class App extends Application {
database = createDatabase(this); database = createDatabase(this);
apiClient = createApiClient(this); apiClient = createApiClient(this);
if (database.userDao().getUsers().size() == 0) { if (database.userDao().getUsers().isEmpty()) {
PreferenceUtil.getInstance(this).setServer(null); PreferenceUtil.getInstance(this).setServer(null);
PreferenceUtil.getInstance(this).setUser(null); PreferenceUtil.getInstance(this).setUser(null);
} }
@ -76,6 +76,7 @@ public class App extends Application {
IDevice device = new AndroidDevice(deviceId, deviceName); IDevice device = new AndroidDevice(deviceId, deviceName);
EventListener eventListener = new EventListener(); EventListener eventListener = new EventListener();
return new ApiClient(httpClient, logger, server, appName, appVersion, device, eventListener); return new ApiClient(httpClient, logger, server, appName, appVersion, device, eventListener);
} }

View file

@ -1,9 +1,12 @@
package org.adrianvictor.geleia.activities; package org.adrianvictor.geleia.activities;
import static org.adrianvictor.geleia.adapter.CustomFragmentStatePagerAdapter.TAG;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -13,10 +16,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.drawerlayout.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
import androidx.lifecycle.Lifecycle;
import com.afollestad.materialcab.attached.AttachedCab; import com.afollestad.materialcab.attached.AttachedCab;
import com.afollestad.materialcab.attached.AttachedCabKt; import com.afollestad.materialcab.attached.AttachedCabKt;
import org.adrianvictor.geleia.activities.base.AbsMusicContentActivity; import org.adrianvictor.geleia.activities.base.AbsMusicContentActivity;
import org.adrianvictor.geleia.fragments.OfflineFragment;
import org.adrianvictor.geleia.interfaces.CabHolder; import org.adrianvictor.geleia.interfaces.CabHolder;
import org.adrianvictor.geleia.util.PreferenceUtil; import org.adrianvictor.geleia.util.PreferenceUtil;
import org.adrianvictor.geleia.util.ThemeUtil; import org.adrianvictor.geleia.util.ThemeUtil;
@ -42,6 +47,7 @@ public class MainActivity extends AbsMusicContentActivity implements CabHolder {
private ActivityMainContentBinding contentBinding; private ActivityMainContentBinding contentBinding;
private NavigationDrawerHeaderBinding navigationBinding; private NavigationDrawerHeaderBinding navigationBinding;
private boolean onLogout; private boolean onLogout;
private boolean pendingShowOffline = false;
@Nullable @Nullable
private AttachedCab cab; private AttachedCab cab;
@ -97,6 +103,24 @@ public class MainActivity extends AbsMusicContentActivity implements CabHolder {
}); });
} }
@Override
public void onStateOffline() {
Log.d(TAG, "onStateOffline() foi chamado.");
Menu menu = binding.navigationView.getMenu();
menu.clear();
menu.add(R.id.navigation_drawer_menu_category_other, R.id.nav_settings, menu.size(), R.string.action_settings);
menu.getItem(menu.size() - 1).setIcon(R.drawable.ic_settings_white_24dp);
menu.add(R.id.navigation_drawer_menu_category_other, R.id.nav_about, menu.size(), R.string.action_about);
menu.getItem(menu.size() - 1).setIcon(R.drawable.ic_info_outline_white_24dp);
menu.add(R.id.navigation_drawer_menu_category_other, R.id.nav_logout, menu.size(), R.string.logout);
menu.getItem(menu.size() - 1).setIcon(R.drawable.ic_exit_to_app_white_48dp);
setUpDrawerLayout();
pendingShowOffline = true;
}
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
@ -108,6 +132,16 @@ public class MainActivity extends AbsMusicContentActivity implements CabHolder {
} }
} }
@Override
protected void onResume() {
super.onResume();
if (pendingShowOffline) {
setCurrentFragment(OfflineFragment.newInstance());
pendingShowOffline = false;
}
}
private void setCurrentFragment(Fragment fragment) { private void setCurrentFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment, null).commit(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment, null).commit();
} }

View file

@ -93,6 +93,9 @@ public class SearchActivity extends AbsMusicContentActivity implements SearchVie
public void onStateOnline() { public void onStateOnline() {
} }
@Override
public void onStateOffline() {}
private void setUpToolBar() { private void setUpToolBar() {
binding.toolbar.setBackgroundColor(PreferenceUtil.getInstance(this).getPrimaryColor()); binding.toolbar.setBackgroundColor(PreferenceUtil.getInstance(this).getPrimaryColor());
setSupportActionBar(binding.toolbar); setSupportActionBar(binding.toolbar);

View file

@ -1,8 +1,13 @@
package org.adrianvictor.geleia.activities; package org.adrianvictor.geleia.activities;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import androidx.annotation.NonNull;
import org.adrianvictor.geleia.App; import org.adrianvictor.geleia.App;
import org.adrianvictor.geleia.R; import org.adrianvictor.geleia.R;
@ -15,6 +20,27 @@ import org.adrianvictor.geleia.util.PreferenceUtil;
import java.util.List; import java.util.List;
public class SplashActivity extends AbsBaseActivity { public class SplashActivity extends AbsBaseActivity {
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, @NonNull Intent intent) {
if (intent.getAction() == null) {
return;
}
switch (intent.getAction()) {
case LoginService.STATE_ONLINE:
NavigationUtil.startMain(context);
finish();
break;
case LoginService.STATE_OFFLINE:
NavigationUtil.startUnreachable(context);
finish();
break;
}
}
};
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -25,6 +51,7 @@ public class SplashActivity extends AbsBaseActivity {
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
unregisterReceiver(receiver);
overridePendingTransition(0, R.anim.fade_delay); overridePendingTransition(0, R.anim.fade_delay);
} }
@ -32,16 +59,27 @@ public class SplashActivity extends AbsBaseActivity {
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
final IntentFilter filter = new IntentFilter();
filter.addAction(LoginService.STATE_ONLINE);
filter.addAction(LoginService.STATE_OFFLINE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
registerReceiver(receiver, filter, Context.RECEIVER_NOT_EXPORTED);
} else {
registerReceiver(receiver, filter);
}
User user = App.getDatabase().userDao().getUser(PreferenceUtil.getInstance(this).getUser()); User user = App.getDatabase().userDao().getUser(PreferenceUtil.getInstance(this).getUser());
List<User> available = App.getDatabase().userDao().getUsers(); List<User> available = App.getDatabase().userDao().getUsers();
if (user == null && available.size() != 0) { if (user == null && !available.isEmpty()) {
NavigationUtil.startSelect(this); NavigationUtil.startSelect(this);
finish();
} else if (user == null) { } else if (user == null) {
NavigationUtil.startLogin(this); NavigationUtil.startLogin(this);
finish();
} else { } else {
startService(new Intent(this, LoginService.class)); startService(new Intent(this, LoginService.class));
new Handler().postDelayed(() -> NavigationUtil.startMain(this), 1000);
} }
} }
} }

View file

@ -0,0 +1,21 @@
package org.adrianvictor.geleia.activities;
import android.os.Bundle;
import android.view.View;
import org.adrianvictor.geleia.R;
import org.adrianvictor.geleia.activities.base.AbsThemeActivity;
import org.adrianvictor.geleia.util.NavigationUtil;
public class UnreachableActivity extends AbsThemeActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_unreachable);
}
public void onSelectClick(View view) {
NavigationUtil.startSelect(this);
}
}

View file

@ -59,7 +59,7 @@ public abstract class AbsBaseActivity extends AbsThemeActivity {
.setPositiveButton(R.string.disable, (dialog, id) -> requestBatteryOptimization()); .setPositiveButton(R.string.disable, (dialog, id) -> requestBatteryOptimization());
new Handler().postDelayed(builder::show, 2000); new Handler().postDelayed(builder::show, 2000);
} else if (permissions.size() != 0 && ActivityCompat.shouldShowRequestPermissionRationale(this, permissions.get(0))) { } else if (!permissions.isEmpty() && ActivityCompat.shouldShowRequestPermissionRationale(this, permissions.get(0))) {
builder.setMessage(getPermissionMessage()) builder.setMessage(getPermissionMessage())
.setTitle(R.string.permissions_denied) .setTitle(R.string.permissions_denied)
.setPositiveButton(R.string.action_grant, (dialog, id) -> requestPermissions()); .setPositiveButton(R.string.action_grant, (dialog, id) -> requestPermissions());

View file

@ -1,14 +1,19 @@
package org.adrianvictor.geleia.activities.base; package org.adrianvictor.geleia.activities.base;
import static org.adrianvictor.geleia.adapter.CustomFragmentStatePagerAdapter.TAG;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.adrianvictor.geleia.App; import org.adrianvictor.geleia.App;
import org.adrianvictor.geleia.fragments.OfflineFragment;
import org.adrianvictor.geleia.interfaces.StateListener; import org.adrianvictor.geleia.interfaces.StateListener;
import org.adrianvictor.geleia.service.LoginService; import org.adrianvictor.geleia.service.LoginService;
import org.adrianvictor.geleia.util.NavigationUtil; import org.adrianvictor.geleia.util.NavigationUtil;
@ -24,7 +29,7 @@ public abstract class AbsMusicContentActivity extends AbsMusicPanelActivity impl
onStateOnline(); onStateOnline();
break; break;
case LoginService.STATE_OFFLINE: case LoginService.STATE_OFFLINE:
NavigationUtil.startLogin(context); NavigationUtil.startSelect(context);
break; break;
} }
} }
@ -39,7 +44,11 @@ public abstract class AbsMusicContentActivity extends AbsMusicPanelActivity impl
filter.addAction(LoginService.STATE_ONLINE); filter.addAction(LoginService.STATE_ONLINE);
filter.addAction(LoginService.STATE_OFFLINE); filter.addAction(LoginService.STATE_OFFLINE);
registerReceiver(receiver, filter); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
registerReceiver(receiver, filter, Context.RECEIVER_NOT_EXPORTED);
} else {
registerReceiver(receiver, filter);
}
if (App.getApiClient() == null) { if (App.getApiClient() == null) {
startService(new Intent(this, LoginService.class)); startService(new Intent(this, LoginService.class));
@ -51,24 +60,14 @@ public abstract class AbsMusicContentActivity extends AbsMusicPanelActivity impl
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
if (App.getApiClient() == null) {
startService(new Intent(this, LoginService.class));
}
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
unregisterReceiver(receiver); unregisterReceiver(receiver);
super.onDestroy(); super.onDestroy();
} }
@Override @Override
public void onStatePolling() { public void onStatePolling() {}
}
@Override
public void onStateOffline() {
}
} }

View file

@ -74,6 +74,11 @@ public class AlbumDetailActivity extends AbsMusicContentActivity implements Pale
}); });
} }
@Override
public void onStateOffline() {
}
@Override @Override
public void onOffsetChanged (AppBarLayout appBarLayout, int verticalOffset) { public void onOffsetChanged (AppBarLayout appBarLayout, int verticalOffset) {
float headerAlpha = Math.max(0, Math.min(1, 1 + (2 * (float) verticalOffset / headerViewHeight))); float headerAlpha = Math.max(0, Math.min(1, 1 + (2 * (float) verticalOffset / headerViewHeight)));
@ -231,6 +236,6 @@ public class AlbumDetailActivity extends AbsMusicContentActivity implements Pale
binding.durationText.setText(MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs))); binding.durationText.setText(MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs)));
binding.albumYearText.setText(MusicUtil.getYearString(album.year)); binding.albumYearText.setText(MusicUtil.getYearString(album.year));
if (album.songs.size() != 0) adapter.swapDataSet(album.songs); if (!album.songs.isEmpty()) adapter.swapDataSet(album.songs);
} }
} }

View file

@ -87,6 +87,11 @@ public class ArtistDetailActivity extends AbsMusicContentActivity implements Pal
}); });
} }
@Override
public void onStateOffline() {
}
@Override @Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
float headerAlpha = Math.max(0, Math.min(1, 1 + (2 * (float) verticalOffset / headerViewHeight))); float headerAlpha = Math.max(0, Math.min(1, 1 + (2 * (float) verticalOffset / headerViewHeight)));
@ -258,7 +263,7 @@ public class ArtistDetailActivity extends AbsMusicContentActivity implements Pal
binding.albumCountText.setText(MusicUtil.getAlbumCountString(this, artist.albums.size())); binding.albumCountText.setText(MusicUtil.getAlbumCountString(this, artist.albums.size()));
binding.durationText.setText(MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, artist.songs))); binding.durationText.setText(MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, artist.songs)));
if (artist.songs.size() != 0) songAdapter.swapDataSet(artist.songs); if (!artist.songs.isEmpty()) songAdapter.swapDataSet(artist.songs);
if (artist.albums.size() != 0) albumAdapter.swapDataSet(artist.albums); if (!artist.albums.isEmpty()) albumAdapter.swapDataSet(artist.albums);
} }
} }

View file

@ -59,6 +59,11 @@ public class GenreDetailActivity extends AbsMusicContentActivity implements CabH
}); });
} }
@Override
public void onStateOffline() {
}
@Override @Override
protected View createContentView() { protected View createContentView() {
binding = ActivityGenreDetailBinding.inflate(getLayoutInflater()); binding = ActivityGenreDetailBinding.inflate(getLayoutInflater());

View file

@ -71,6 +71,11 @@ public class PlaylistDetailActivity extends AbsMusicContentActivity implements C
}); });
} }
@Override
public void onStateOffline() {
}
@Override @Override
protected View createContentView() { protected View createContentView() {
binding = ActivityPlaylistDetailBinding.inflate(getLayoutInflater()); binding = ActivityPlaylistDetailBinding.inflate(getLayoutInflater());

View file

@ -180,7 +180,7 @@ public abstract class CustomFragmentStatePagerAdapter extends PagerAdapter {
@Override @Override
public Parcelable saveState() { public Parcelable saveState() {
Bundle state = null; Bundle state = null;
if (mSavedState.size() > 0) { if (!mSavedState.isEmpty()) {
state = new Bundle(); state = new Bundle();
Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()]; Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()];
mSavedState.toArray(fss); mSavedState.toArray(fss);

View file

@ -31,7 +31,7 @@ public class SongShareDialog extends DialogFragment {
final String currentlyListening = getString(R.string.currently_listening_to_x_by_x, song.title, song.artistName); final String currentlyListening = getString(R.string.currently_listening_to_x_by_x, song.title, song.artistName);
return new MaterialDialog.Builder(requireActivity()) return new MaterialDialog.Builder(requireActivity())
.title(R.string.what_do_you_want_to_share) .title(R.string.what_do_you_want_to_share)
.items(getString(R.string.the_audio_file), "\u201C" + currentlyListening + "\u201D") .items(getString(R.string.the_audio_file), "" + currentlyListening + "")
.itemsCallback((materialDialog, view, i, charSequence) -> { .itemsCallback((materialDialog, view, i, charSequence) -> {
switch (i) { switch (i) {
case 0: case 0:

View file

@ -0,0 +1,25 @@
package org.adrianvictor.geleia.fragments;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import org.adrianvictor.geleia.R;
public class OfflineFragment extends Fragment {
public static OfflineFragment newInstance() {
return new OfflineFragment();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_offline, container, false);
}
}

View file

@ -273,7 +273,7 @@ public class MusicPlayerRemote {
public static boolean playNext(Song song) { public static boolean playNext(Song song) {
if (musicService != null && musicService.queueManager != null) { if (musicService != null && musicService.queueManager != null) {
if (getPlayingQueue().size() > 0) { if (!getPlayingQueue().isEmpty()) {
musicService.queueManager.addSong(getPosition() + 1, song); musicService.queueManager.addSong(getPosition() + 1, song);
} else { } else {
List<Song> queue = new ArrayList<>(); List<Song> queue = new ArrayList<>();
@ -290,7 +290,7 @@ public class MusicPlayerRemote {
public static boolean playNext(@NonNull List<Song> songs) { public static boolean playNext(@NonNull List<Song> songs) {
if (musicService != null && musicService.queueManager != null) { if (musicService != null && musicService.queueManager != null) {
if (getPlayingQueue().size() > 0) { if (!getPlayingQueue().isEmpty()) {
musicService.queueManager.addSongs(getPosition() + 1, songs); musicService.queueManager.addSongs(getPosition() + 1, songs);
} else { } else {
openQueue(songs, 0, false); openQueue(songs, 0, false);
@ -306,7 +306,7 @@ public class MusicPlayerRemote {
public static boolean enqueue(Song song) { public static boolean enqueue(Song song) {
if (musicService != null && musicService.queueManager != null) { if (musicService != null && musicService.queueManager != null) {
if (getPlayingQueue().size() > 0) { if (!getPlayingQueue().isEmpty()) {
musicService.queueManager.addSong(song); musicService.queueManager.addSong(song);
} else { } else {
List<Song> queue = new ArrayList<>(); List<Song> queue = new ArrayList<>();
@ -323,7 +323,7 @@ public class MusicPlayerRemote {
public static boolean enqueue(@NonNull List<Song> songs) { public static boolean enqueue(@NonNull List<Song> songs) {
if (musicService != null && musicService.queueManager != null) { if (musicService != null && musicService.queueManager != null) {
if (getPlayingQueue().size() > 0) { if (!getPlayingQueue().isEmpty()) {
musicService.queueManager.addSongs(songs); musicService.queueManager.addSongs(songs);
} else { } else {
openQueue(songs, 0, false); openQueue(songs, 0, false);

View file

@ -29,10 +29,10 @@ public class Album implements Parcelable {
this.title = itemDto.getName(); this.title = itemDto.getName();
this.year = itemDto.getProductionYear() != null ? itemDto.getProductionYear() : 0; this.year = itemDto.getProductionYear() != null ? itemDto.getProductionYear() : 0;
if (itemDto.getAlbumArtists().size() != 0) { if (!itemDto.getAlbumArtists().isEmpty()) {
this.artistId = itemDto.getAlbumArtists().get(0).getId(); this.artistId = itemDto.getAlbumArtists().get(0).getId();
this.artistName = itemDto.getAlbumArtists().get(0).getName(); this.artistName = itemDto.getAlbumArtists().get(0).getName();
} else if (itemDto.getArtistItems().size() != 0) { } else if (!itemDto.getArtistItems().isEmpty()) {
this.artistId = itemDto.getArtistItems().get(0).getId(); this.artistId = itemDto.getArtistItems().get(0).getId();
this.artistName = itemDto.getArtistItems().get(0).getName(); this.artistName = itemDto.getArtistItems().get(0).getName();
} }

View file

@ -67,10 +67,10 @@ public class Song implements Parcelable {
this.albumId = itemDto.getAlbumId(); this.albumId = itemDto.getAlbumId();
this.albumName = itemDto.getAlbum(); this.albumName = itemDto.getAlbum();
if (itemDto.getArtistItems().size() != 0) { if (!itemDto.getArtistItems().isEmpty()) {
this.artistId = itemDto.getArtistItems().get(0).getId(); this.artistId = itemDto.getArtistItems().get(0).getId();
this.artistName = itemDto.getArtistItems().get(0).getName(); this.artistName = itemDto.getArtistItems().get(0).getName();
} else if (itemDto.getAlbumArtists().size() != 0) { } else if (!itemDto.getAlbumArtists().isEmpty()) {
this.artistId = itemDto.getAlbumArtists().get(0).getId(); this.artistId = itemDto.getAlbumArtists().get(0).getId();
this.artistName = itemDto.getAlbumArtists().get(0).getName(); this.artistName = itemDto.getAlbumArtists().get(0).getName();
} }
@ -93,7 +93,7 @@ public class Song implements Parcelable {
this.supportsTranscoding = source.getSupportsTranscoding(); this.supportsTranscoding = source.getSupportsTranscoding();
if (source.getMediaStreams() != null && source.getMediaStreams().size() != 0) { if (source.getMediaStreams() != null && !source.getMediaStreams().isEmpty()) {
MediaStream stream = source.getMediaStreams().get(0); MediaStream stream = source.getMediaStreams().get(0);
this.codec = stream.getCodec(); this.codec = stream.getCodec();

View file

@ -46,6 +46,21 @@ public class LoginService extends Service {
if (user == null) { if (user == null) {
Toast.makeText(this, context.getResources().getString(R.string.error_unexpected), Toast.LENGTH_SHORT).show(); Toast.makeText(this, context.getResources().getString(R.string.error_unexpected), Toast.LENGTH_SHORT).show();
sendBroadcast(new Intent(STATE_OFFLINE));
return;
}
if (App.getApiClient() == null) {
try {
App.createApiClient(context);
} catch (Exception e) {
sendBroadcast(new Intent(STATE_OFFLINE));
return;
}
}
if (App.getApiClient() == null) {
sendBroadcast(new Intent(STATE_OFFLINE));
return; return;
} }

View file

@ -83,7 +83,7 @@ public class DownloadNotification {
songs.clear(); songs.clear();
} }
if (songs.size() != 0) { if (!songs.isEmpty()) {
return; return;
} }

View file

@ -50,7 +50,7 @@ public class MusicUtil {
List<Codec> codecs = preferenceUtil.getDirectPlayCodecs(); List<Codec> codecs = preferenceUtil.getDirectPlayCodecs();
Stream<String> values = codecs.stream().map(codec -> codec.value); Stream<String> values = codecs.stream().map(codec -> codec.value);
if (codecs.size() != 0) { if (!codecs.isEmpty()) {
builder.append("&Container=").append(values.collect(Collectors.joining(","))); builder.append("&Container=").append(values.collect(Collectors.joining(",")));
} }
@ -111,7 +111,7 @@ public class MusicUtil {
@NonNull @NonNull
public static String getArtistInfoString(@NonNull final Context context, @NonNull final Artist artist) { public static String getArtistInfoString(@NonNull final Context context, @NonNull final Artist artist) {
return artist.genres.size() != 0 ? artist.genres.get(0).name : ""; return !artist.genres.isEmpty() ? artist.genres.get(0).name : "";
} }
@NonNull @NonNull

View file

@ -12,6 +12,7 @@ import androidx.core.util.Pair;
import org.adrianvictor.geleia.activities.LoginActivity; import org.adrianvictor.geleia.activities.LoginActivity;
import org.adrianvictor.geleia.activities.MainActivity; import org.adrianvictor.geleia.activities.MainActivity;
import org.adrianvictor.geleia.activities.SelectActivity; import org.adrianvictor.geleia.activities.SelectActivity;
import org.adrianvictor.geleia.activities.UnreachableActivity;
import org.adrianvictor.geleia.model.Album; import org.adrianvictor.geleia.model.Album;
import org.adrianvictor.geleia.model.Artist; import org.adrianvictor.geleia.model.Artist;
import org.adrianvictor.geleia.model.Genre; import org.adrianvictor.geleia.model.Genre;
@ -61,6 +62,13 @@ public class NavigationUtil {
context.startActivity(intent); context.startActivity(intent);
} }
public static void startUnreachable(Context context) {
final Intent intent = new Intent(context, UnreachableActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
}
public static void startSelect(Context context) { public static void startSelect(Context context) {
final Intent intent = new Intent(context, SelectActivity.class); final Intent intent = new Intent(context, SelectActivity.class);

View file

@ -48,7 +48,7 @@ public class PlaylistUtil {
PlaylistCreationRequest request = new PlaylistCreationRequest(); PlaylistCreationRequest request = new PlaylistCreationRequest();
request.setUserId(App.getApiClient().getCurrentUserId()); request.setUserId(App.getApiClient().getCurrentUserId());
request.setName(name); request.setName(name);
if (ids.size() != 0) request.setItemIdList(ids); if (!ids.isEmpty()) request.setItemIdList(ids);
App.getApiClient().CreatePlaylist(request, new Response<>()); App.getApiClient().CreatePlaylist(request, new Response<>());
} }

View file

@ -448,7 +448,6 @@ public final class PreferenceUtil {
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
@SuppressWarnings("SimplifyStreamApiCallChains")
public void setCategories(List<Category> categories) { public void setCategories(List<Category> categories) {
List<String> values = categories.stream().map(category -> { List<String> values = categories.stream().map(category -> {
return category.select ? category.toString() : category.toString().toLowerCase(); return category.select ? category.toString() : category.toString().toLowerCase();

View file

@ -36,7 +36,7 @@ public class DynamicShortcutManager {
} }
public void initDynamicShortcuts() { public void initDynamicShortcuts() {
if (shortcutManager.getDynamicShortcuts().size() == 0) { if (shortcutManager.getDynamicShortcuts().isEmpty()) {
shortcutManager.setDynamicShortcuts(getDefaultShortcuts()); shortcutManager.setDynamicShortcuts(getDefaultShortcuts());
} }
} }

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="org.adrianvictor.geleia.activities.UnreachableActivity">
<include layout="@layout/status_bar" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_margin="16dp"
android:clipToPadding="false"
android:isScrollContainer="true">
<include layout="@layout/fragment_offline" />
</ScrollView>
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:layout_marginBottom="16dp"
android:onClick="onSelectClick"
android:text="@string/change_server" />
</LinearLayout>

View file

@ -0,0 +1,40 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_margin="32dp"
tools:context=".fragments.OfflineFragment">
<TextView
android:id="@+id/offline_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:text="@string/sad_face"
android:textAppearance="@style/TextAppearance.AppCompat.Display3" />
<TextView
android:id="@+id/error_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/offline_icon"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:text="@string/oops"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
<TextView
android:id="@+id/error_messsage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/error_title"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:text="@string/server_is_unreachable"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
</RelativeLayout>

View file

@ -236,5 +236,10 @@
<string name="dkanada_summary">Forking Phonograph and making Gelli</string> <string name="dkanada_summary">Forking Phonograph and making Gelli</string>
<string name="adrianvictor">Adrian Victor</string> <string name="adrianvictor">Adrian Victor</string>
<string name="error_notification_title">An error occurred in Jamfish.</string> <string name="error_notification_title">An error occurred in Jamfish.</string>
<string name="offline">You are offline.</string>
<string name="change_server">Change server</string>
<string name="oops">Oops! I did it again...</string>
<string name="sad_face">;(</string>
<string name="server_is_unreachable">Sorry, but we couldn\'t reach this server right now.</string>
</resources> </resources>