Skip to content

Commit

Permalink
Movable FloatingButton. Refresh on swipe. Fixes and enhancements.
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreyPavlenko committed Dec 10, 2020
1 parent 3135c93 commit 21b37f9
Show file tree
Hide file tree
Showing 21 changed files with 144 additions and 52 deletions.
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ ext {
VERSION_CODE = 79
VERSION_NAME = "1.7.3"
SDK_MIN_VERSION = 23
SDK_TARGET_VERSION = 29
SDK_COMPILE_VERSION = 29
SDK_TARGET_VERSION = 30
SDK_COMPILE_VERSION = 30
BUILD_TOOLS_VERSION = "29.0.2"
ABI_FILTERS = (abi != null) ? abi.split(",") : ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']
localProps = gradle.ext.localProps
Expand All @@ -15,6 +15,7 @@ ext {
ANDROIDX_MEDIA_VERSION = '1.2.0'
ANDROIDX_APPCOMPAT_VERSION = '1.2.0'
ANDROIDX_CONSTRAINTLAYOUT_VERSION = '2.0.1'
ANDROIDX_SWIPEREFRESHLAYOUT_VERSION = '1.1.0'
}

buildscript {
Expand Down
1 change: 1 addition & 0 deletions fermata/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,6 @@ dependencies {
implementation 'androidx.appcompat:appcompat:' + ANDROIDX_APPCOMPAT_VERSION
implementation 'com.google.android.material:material:' + ANDROID_MATERIAL_VERSION
implementation "androidx.constraintlayout:constraintlayout:" + ANDROIDX_CONSTRAINTLAYOUT_VERSION
implementation "androidx.swiperefreshlayout:swiperefreshlayout:" + ANDROIDX_SWIPEREFRESHLAYOUT_VERSION
implementation 'com.google.android.play:core:' + ANDROID_PLAY_CORE_VERSION
}
5 changes: 5 additions & 0 deletions fermata/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>

<intent-filter>
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<service
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class MediaEngineManager implements PreferenceStore.Listener {
private static final String MODULE_EXO = "exoplayer";
private static final String MODULE_VLC = "vlc";
final MediaLib lib;
final MediaEngineProvider mediaPlayer;
final MediaPlayerEngineProvider mediaPlayer;
MediaEngineProvider exoPlayer;
MediaEngineProvider vlcPlayer;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,26 +90,30 @@ public boolean getMediaMetadata(MetadataBuilder meta, PlayableItem item) {
}

if (isValidBitmap(bm)) meta.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bm);

return true;
} catch (Throwable ex) {
Log.d(ex, "Failed to retrieve media metadata of ", item.getLocation());
if (meta.getDuration() != 0) return true;

MediaPlayer mp = null;
try {
mp = MediaPlayer.create(ctx, item.getLocation());
if (mp == null) return false;

meta.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mp.getDuration());
} catch (Throwable ex2) {
Log.d(ex2, "Failed to retrieve duration of ", item.getLocation());
return false;
} finally {
if (mp != null) mp.release();
}
return false;
} finally {
if (mmr != null) mmr.release();
}
}

public boolean getDuration(MetadataBuilder meta, PlayableItem item) {
if (meta.getDuration() != 0) return true;

return true;
MediaPlayer mp = null;
try {
mp = MediaPlayer.create(ctx, item.getLocation());
if (mp == null) return false;
meta.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mp.getDuration());
return true;
} catch (Throwable ex2) {
Log.d(ex2, "Failed to retrieve duration of ", item.getLocation());
return false;
} finally {
if (mp != null) mp.release();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,13 @@ private MetadataBuilder load(PlayableItem item) {
}
}

MediaEngineProvider mp = mgr.mediaPlayer;
MediaEngineProvider vlc = mgr.vlcPlayer;

if (file.isLocalFile() && file.getName().endsWith(".flac")) {
// VLC does not extract images from flac, thus prefer Android extractor for local files
if (!mp.getMediaMetadata(mb, item) && (vlc != null)) {
// Seems flac is not supported, trying VLC
vlc.getMediaMetadata(mb, item);
}
} else if (vlc != null) {
if (!vlc.getMediaMetadata(mb, item) || !mb.hasImage()) mp.getMediaMetadata(mb, item);
MediaPlayerEngineProvider mp = mgr.mediaPlayer;

if (!mp.getMediaMetadata(mb, item)) {
MediaEngineProvider vlc = mgr.vlcPlayer;
if ((vlc == null) || !vlc.getMediaMetadata(mb, item)) mp.getDuration(mb, item);
} else {
mp.getMediaMetadata(mb, item);
mp.getDuration(mb, item);
}

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import me.aap.utils.text.SharedTextBuilder;

import static java.util.Objects.requireNonNull;
import static me.aap.fermata.BuildConfig.DEBUG;
import static me.aap.utils.async.Completed.completed;
import static me.aap.utils.collection.CollectionUtils.mapToArray;

Expand All @@ -33,14 +34,29 @@ class DefaultPlaylist extends ItemContainer<PlayableItem> implements Playlist, P
private final int playlistId;
private final SharedPreferenceStore playlistPrefStore;

public DefaultPlaylist(String id, BrowsableItem parent, int playlistId) {
private DefaultPlaylist(String id, BrowsableItem parent, int playlistId) {
super(id, parent, null);
this.playlistId = playlistId;
SharedPreferences prefs = getLib().getContext().getSharedPreferences("playlist_" + playlistId,
Context.MODE_PRIVATE);
playlistPrefStore = SharedPreferenceStore.create(prefs, getLib().getPrefs());
}

public static DefaultPlaylist create(String id, BrowsableItem parent, int playlistId, DefaultMediaLib lib) {
synchronized (lib.cacheLock()) {
Item i = lib.getFromCache(id);

if (i != null) {
DefaultPlaylist pl = (DefaultPlaylist) i;
if (DEBUG && !parent.equals(pl.getParent())) throw new AssertionError();
if (DEBUG && !id.equals(pl.getId())) throw new AssertionError();
return pl;
} else {
return new DefaultPlaylist(id, parent, playlistId);
}
}
}

@Override
protected FutureSupplier<String> buildTitle() {
return completed(getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,13 @@ public BrowsableItemPrefs getPrefs() {
@Override
public FutureSupplier<List<Item>> listChildren() {
int[] ids = getPlaylistIdsPref();
DefaultMediaLib lib = getLib();
List<Item> children = new ArrayList<>(ids.length);

for (int id : ids) {
SharedTextBuilder tb = SharedTextBuilder.get();
tb.append(SCHEME).append(':').append(id).append(':');
children.add(new DefaultPlaylist(tb.releaseString(), this, id));
children.add(DefaultPlaylist.create(tb.releaseString(), this, id, lib));
}

return completed(children);
Expand Down Expand Up @@ -132,7 +133,7 @@ public Playlist addItem(CharSequence name) {
int playlistId = getPlaylistsCounterPref() + 1;
SharedTextBuilder tb = SharedTextBuilder.get();
tb.append(SCHEME).append(':').append(playlistId).append(':');
DefaultPlaylist pl = new DefaultPlaylist(tb.releaseString(), this, playlistId);
DefaultPlaylist pl = DefaultPlaylist.create(tb.releaseString(), this, playlistId, getLib());
setPlaylistsCounterPref(playlistId);
pl.setPlaylistNamePref(n);
super.addItem(pl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -478,6 +479,17 @@ private void init() {
controlPanel = a.findViewById(R.id.control_panel);
floatingButton = a.findViewById(R.id.floating_button);
controlPanel.bind(getMediaServiceBinder());

SwipeRefreshLayout refresh = a.findViewById(R.id.swiperefresh);
refresh.setOnRefreshListener(() -> {
ActivityFragment f = getActiveFragment();
if (f != null) f.onRefresh(refresh::setRefreshing);
});
refresh.setOnChildScrollUpCallback((p, c) -> {
if (isMenuActive()) return true;
ActivityFragment f = getActiveFragment();
return (f != null) && f.canScrollUp();
});
}

private void onMediaServiceBind(FermataServiceUiBinder b, Throwable err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

Expand Down Expand Up @@ -206,6 +207,11 @@ private void addFolderPicker(VirtualFileSystem fs) {
f.setFileConsumer(this::addFolderResult);
}

public boolean canScrollUp() {
View v = getView();
return (v != null) && (v.getScrollY() > 0);
}

private void addFolderVfs(String provId, @StringRes int name) {
FermataVfsManager mgr = getLib().getVfsManager();
mgr.getProvider(provId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import me.aap.fermata.ui.view.MediaItemView;
import me.aap.fermata.ui.view.MediaItemWrapper;
import me.aap.utils.async.FutureSupplier;
import me.aap.utils.function.BooleanConsumer;
import me.aap.utils.pref.PreferenceStore;
import me.aap.utils.ui.view.FloatingButton;
import me.aap.utils.ui.view.ToolBarView;
Expand Down Expand Up @@ -176,15 +177,20 @@ public boolean onBackPressed() {
return true;
}

public void reload() {
@Override
public void onRefresh(BooleanConsumer refreshing) {
reload().onCompletion((r,f)->refreshing.accept(false));
}

public FutureSupplier<?> reload() {
discardSelection();
getAdapter().reload();
return getAdapter().reload();
}

public void refresh() {
public FutureSupplier<?> refresh() {
getLib().getVfsManager().clearCache();
getAdapter().getParent().refresh();
reload();
return reload();
}

public void rescan() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,8 @@ private OverlayMenu getMenu(MainActivityDelegate a) {
}

private void setShowHideBarsIcon(MainActivityDelegate a) {
showHideBars.setImageResource(a.isBarsHidden() ? R.drawable.expand : R.drawable.collapse);
App.get().getHandler().post(() ->
showHideBars.setImageResource(a.isBarsHidden() ? R.drawable.expand : R.drawable.collapse));
}

private MainActivityDelegate getActivity() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ public void setFilter(String filter) {
}
}

public void reload() {
public FutureSupplier<?> reload() {
getListView().discardSelection();
setParent(getParent());
return setParent(getParent());
}

public void refresh() {
Expand Down
24 changes: 16 additions & 8 deletions fermata/src/main/res/layout/main_activity.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
Expand All @@ -11,23 +12,29 @@
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
app:layout_constraintBottom_toTopOf="@id/frame_layout"
app:layout_constraintBottom_toTopOf="@id/swiperefresh"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<me.aap.fermata.ui.view.FrameView
android:id="@+id/frame_layout"
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="?android:colorBackground"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toTopOf="@id/control_panel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tool_bar"
app:layout_constraintVertical_weight="1"
tools:context=".ui.activity.MainActivity" />
app:layout_constraintVertical_weight="1">

<me.aap.fermata.ui.view.FrameView
android:id="@+id/frame_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:colorBackground"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".ui.activity.MainActivity" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

<me.aap.fermata.ui.view.ControlPanelView
android:id="@+id/control_panel"
Expand All @@ -37,7 +44,7 @@
app:layout_constraintBottom_toTopOf="@id/nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/frame_layout" />
app:layout_constraintTop_toBottomOf="@id/swiperefresh" />

<me.aap.utils.ui.view.NavBarView
android:id="@+id/nav_bar"
Expand All @@ -55,6 +62,7 @@
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:layout_marginBottom="20dp"
android:alpha="0.5"
android:elevation="10dp"
app:layout_constraintBottom_toTopOf="@id/control_panel"
app:layout_constraintEnd_toEndOf="parent" />
Expand Down
3 changes: 2 additions & 1 deletion modules/web/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ dependencies {
implementation 'androidx.appcompat:appcompat:' + ANDROIDX_APPCOMPAT_VERSION
implementation 'com.google.android.material:material:' + ANDROID_MATERIAL_VERSION
implementation "androidx.constraintlayout:constraintlayout:" + ANDROIDX_CONSTRAINTLAYOUT_VERSION
implementation 'androidx.webkit:webkit:1.2.0'
implementation "androidx.swiperefreshlayout:swiperefreshlayout:" + ANDROIDX_SWIPEREFRESHLAYOUT_VERSION
implementation 'androidx.webkit:webkit:1.3.0'
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import me.aap.fermata.ui.activity.MainActivityDelegate;
import me.aap.utils.async.Completed;
import me.aap.utils.async.Promise;
import me.aap.utils.function.BooleanConsumer;
import me.aap.utils.log.Log;

import static me.aap.utils.ui.activity.ActivityListener.FRAGMENT_CONTENT_CHANGED;
Expand All @@ -22,11 +23,15 @@
* @author Andrey Pavlenko
*/
public class FermataWebClient extends WebViewClientCompat {
BooleanConsumer loading;

@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
MainActivityDelegate a = MainActivityDelegate.get(view.getContext());
a.setContentLoading(new Promise<>());
if (loading != null) {
loading.accept(true);
} else {
MainActivityDelegate.get(view.getContext()).setContentLoading(new Promise<>());
}
super.onPageStarted(view, url, favicon);
}

Expand All @@ -35,6 +40,12 @@ public void onPageFinished(WebView view, String url) {
FermataWebView v = (FermataWebView) view;
MainActivityDelegate a = MainActivityDelegate.get(view.getContext());
a.setContentLoading(Completed.completedVoid());

if (loading != null) {
loading.accept(false);
loading = null;
}

super.onPageFinished(view, url);
((FermataWebView) view).hideKeyboard();
v.pageLoaded(url);
Expand Down
Loading

0 comments on commit 21b37f9

Please sign in to comment.