sdk 0.74.0. Publish and Publishes pages.
|
@ -62,6 +62,10 @@ dependencies {
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||||
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
|
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
|
||||||
implementation 'androidx.preference:preference:1.1.1'
|
implementation 'androidx.preference:preference:1.1.1'
|
||||||
|
implementation 'androidx.camera:camera-camera2:1.0.0-beta03'
|
||||||
|
implementation 'androidx.camera:camera-lifecycle:1.0.0-beta03'
|
||||||
|
implementation 'androidx.camera:camera-view:1.0.0-alpha10'
|
||||||
|
|
||||||
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
||||||
implementation 'com.squareup.okhttp3:okhttp:4.4.1'
|
implementation 'com.squareup.okhttp3:okhttp:4.4.1'
|
||||||
implementation 'com.google.firebase:firebase-analytics:17.4.0'
|
implementation 'com.google.firebase:firebase-analytics:17.4.0'
|
||||||
|
@ -91,8 +95,8 @@ dependencies {
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||||
|
|
||||||
__32bitImplementation files('libs/lbrysdk-0.73.1-release__arm.aar')
|
__32bitImplementation files('libs/lbrysdk-0.74.0-release__arm.aar')
|
||||||
__64bitImplementation files('libs/lbrysdk-0.73.1-release__arm64.aar')
|
__64bitImplementation files('libs/lbrysdk-0.74.0-release__arm64.aar')
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
package="io.lbry.browser"
|
package="io.lbry.browser"
|
||||||
android:installLocation="auto">
|
android:installLocation="auto">
|
||||||
|
|
||||||
|
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
|
|
@ -16,7 +16,6 @@ import android.content.res.Configuration;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
@ -30,7 +29,6 @@ import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.Window;
|
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
@ -96,6 +94,7 @@ import io.lbry.browser.adapter.UrlSuggestionListAdapter;
|
||||||
import io.lbry.browser.data.DatabaseHelper;
|
import io.lbry.browser.data.DatabaseHelper;
|
||||||
import io.lbry.browser.dialog.ContentScopeDialogFragment;
|
import io.lbry.browser.dialog.ContentScopeDialogFragment;
|
||||||
import io.lbry.browser.exceptions.LbryUriException;
|
import io.lbry.browser.exceptions.LbryUriException;
|
||||||
|
import io.lbry.browser.listener.CameraPermissionListener;
|
||||||
import io.lbry.browser.listener.DownloadActionListener;
|
import io.lbry.browser.listener.DownloadActionListener;
|
||||||
import io.lbry.browser.listener.FetchChannelsListener;
|
import io.lbry.browser.listener.FetchChannelsListener;
|
||||||
import io.lbry.browser.listener.SdkStatusListener;
|
import io.lbry.browser.listener.SdkStatusListener;
|
||||||
|
@ -133,6 +132,8 @@ import io.lbry.browser.ui.following.FileViewFragment;
|
||||||
import io.lbry.browser.ui.following.FollowingFragment;
|
import io.lbry.browser.ui.following.FollowingFragment;
|
||||||
import io.lbry.browser.ui.library.LibraryFragment;
|
import io.lbry.browser.ui.library.LibraryFragment;
|
||||||
import io.lbry.browser.ui.other.AboutFragment;
|
import io.lbry.browser.ui.other.AboutFragment;
|
||||||
|
import io.lbry.browser.ui.publish.PublishFragment;
|
||||||
|
import io.lbry.browser.ui.publish.PublishesFragment;
|
||||||
import io.lbry.browser.ui.search.SearchFragment;
|
import io.lbry.browser.ui.search.SearchFragment;
|
||||||
import io.lbry.browser.ui.other.SettingsFragment;
|
import io.lbry.browser.ui.other.SettingsFragment;
|
||||||
import io.lbry.browser.ui.allcontent.AllContentFragment;
|
import io.lbry.browser.ui.allcontent.AllContentFragment;
|
||||||
|
@ -164,7 +165,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
public static Claim nowPlayingClaim;
|
public static Claim nowPlayingClaim;
|
||||||
public static boolean startingFilePickerActivity = false;
|
public static boolean startingFilePickerActivity = false;
|
||||||
public static boolean startingShareActivity = false;
|
public static boolean startingShareActivity = false;
|
||||||
public static boolean startingStoragePermissionRequest = false;
|
public static boolean startingPermissionRequest = false;
|
||||||
public static boolean startingSignInFlowActivity = false;
|
public static boolean startingSignInFlowActivity = false;
|
||||||
private boolean enteringPIPMode = false;
|
private boolean enteringPIPMode = false;
|
||||||
private boolean fullSyncInProgress = false;
|
private boolean fullSyncInProgress = false;
|
||||||
|
@ -185,8 +186,10 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
fragmentClassNavIdMap.put(EditorsChoiceFragment.class, NavMenuItem.ID_ITEM_EDITORS_CHOICE);
|
fragmentClassNavIdMap.put(EditorsChoiceFragment.class, NavMenuItem.ID_ITEM_EDITORS_CHOICE);
|
||||||
fragmentClassNavIdMap.put(AllContentFragment.class, NavMenuItem.ID_ITEM_ALL_CONTENT);
|
fragmentClassNavIdMap.put(AllContentFragment.class, NavMenuItem.ID_ITEM_ALL_CONTENT);
|
||||||
|
|
||||||
|
fragmentClassNavIdMap.put(PublishFragment.class, NavMenuItem.ID_ITEM_NEW_PUBLISH);
|
||||||
fragmentClassNavIdMap.put(ChannelManagerFragment.class, NavMenuItem.ID_ITEM_CHANNELS);
|
fragmentClassNavIdMap.put(ChannelManagerFragment.class, NavMenuItem.ID_ITEM_CHANNELS);
|
||||||
fragmentClassNavIdMap.put(LibraryFragment.class, NavMenuItem.ID_ITEM_LIBRARY);
|
fragmentClassNavIdMap.put(LibraryFragment.class, NavMenuItem.ID_ITEM_LIBRARY);
|
||||||
|
fragmentClassNavIdMap.put(PublishesFragment.class, NavMenuItem.ID_ITEM_PUBLISHES);
|
||||||
|
|
||||||
fragmentClassNavIdMap.put(WalletFragment.class, NavMenuItem.ID_ITEM_WALLET);
|
fragmentClassNavIdMap.put(WalletFragment.class, NavMenuItem.ID_ITEM_WALLET);
|
||||||
fragmentClassNavIdMap.put(RewardsFragment.class, NavMenuItem.ID_ITEM_REWARDS);
|
fragmentClassNavIdMap.put(RewardsFragment.class, NavMenuItem.ID_ITEM_REWARDS);
|
||||||
|
@ -202,6 +205,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int REQUEST_STORAGE_PERMISSION = 1001;
|
public static final int REQUEST_STORAGE_PERMISSION = 1001;
|
||||||
|
public static final int REQUEST_CAMERA_PERMISSION = 1002;
|
||||||
public static final int REQUEST_SIMPLE_SIGN_IN = 2001;
|
public static final int REQUEST_SIMPLE_SIGN_IN = 2001;
|
||||||
public static final int REQUEST_WALLET_SYNC_SIGN_IN = 2002;
|
public static final int REQUEST_WALLET_SYNC_SIGN_IN = 2002;
|
||||||
public static final int REQUEST_REWARDS_VERIFY_SIGN_IN = 2003;
|
public static final int REQUEST_REWARDS_VERIFY_SIGN_IN = 2003;
|
||||||
|
@ -270,6 +274,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
@Getter
|
@Getter
|
||||||
private DatabaseHelper dbHelper;
|
private DatabaseHelper dbHelper;
|
||||||
private int selectedMenuItemId = -1;
|
private int selectedMenuItemId = -1;
|
||||||
|
private List<CameraPermissionListener> cameraPermissionListeners;
|
||||||
private List<DownloadActionListener> downloadActionListeners;
|
private List<DownloadActionListener> downloadActionListeners;
|
||||||
private List<SdkStatusListener> sdkStatusListeners;
|
private List<SdkStatusListener> sdkStatusListeners;
|
||||||
private List<StoragePermissionListener> storagePermissionListeners;
|
private List<StoragePermissionListener> storagePermissionListeners;
|
||||||
|
@ -296,25 +301,6 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
private static final int STARTUP_STAGE_SUBSCRIPTIONS_LOADED = 6;
|
private static final int STARTUP_STAGE_SUBSCRIPTIONS_LOADED = 6;
|
||||||
private static final int STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED = 7;
|
private static final int STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED = 7;
|
||||||
|
|
||||||
private final List<Integer> supportedMenuItemIds = Arrays.asList(
|
|
||||||
// find content
|
|
||||||
NavMenuItem.ID_ITEM_FOLLOWING,
|
|
||||||
NavMenuItem.ID_ITEM_EDITORS_CHOICE,
|
|
||||||
NavMenuItem.ID_ITEM_ALL_CONTENT,
|
|
||||||
|
|
||||||
// your content
|
|
||||||
NavMenuItem.ID_ITEM_CHANNELS,
|
|
||||||
NavMenuItem.ID_ITEM_LIBRARY,
|
|
||||||
|
|
||||||
// wallet
|
|
||||||
NavMenuItem.ID_ITEM_WALLET,
|
|
||||||
NavMenuItem.ID_ITEM_REWARDS,
|
|
||||||
NavMenuItem.ID_ITEM_INVITES,
|
|
||||||
|
|
||||||
NavMenuItem.ID_ITEM_SETTINGS,
|
|
||||||
NavMenuItem.ID_ITEM_ABOUT
|
|
||||||
);
|
|
||||||
|
|
||||||
public boolean isDarkMode() {
|
public boolean isDarkMode() {
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
return sp.getBoolean(PREFERENCE_KEY_DARK_MODE, false);
|
return sp.getBoolean(PREFERENCE_KEY_DARK_MODE, false);
|
||||||
|
@ -391,6 +377,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
// other
|
// other
|
||||||
pendingSyncSetQueue = new ArrayList<>();
|
pendingSyncSetQueue = new ArrayList<>();
|
||||||
openNavFragments = new HashMap<>();
|
openNavFragments = new HashMap<>();
|
||||||
|
cameraPermissionListeners = new ArrayList<>();
|
||||||
downloadActionListeners = new ArrayList<>();
|
downloadActionListeners = new ArrayList<>();
|
||||||
sdkStatusListeners = new ArrayList<>();
|
sdkStatusListeners = new ArrayList<>();
|
||||||
storagePermissionListeners = new ArrayList<>();
|
storagePermissionListeners = new ArrayList<>();
|
||||||
|
@ -468,13 +455,9 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!supportedMenuItemIds.contains(menuItem.getId())) {
|
|
||||||
Snackbar.make(navItemsView, R.string.not_yet_implemented, Snackbar.LENGTH_LONG).show();
|
|
||||||
} else {
|
|
||||||
navMenuAdapter.setCurrentItem(menuItem);
|
navMenuAdapter.setCurrentItem(menuItem);
|
||||||
shouldOpenUserSelectedMenuItem = true;
|
shouldOpenUserSelectedMenuItem = true;
|
||||||
selectedMenuItemId = menuItem.getId();
|
selectedMenuItemId = menuItem.getId();
|
||||||
}
|
|
||||||
closeDrawer();
|
closeDrawer();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -496,8 +479,8 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
specialRouteFragmentClassMap.put("invite", InvitesFragment.class);
|
specialRouteFragmentClassMap.put("invite", InvitesFragment.class);
|
||||||
specialRouteFragmentClassMap.put("invites", InvitesFragment.class);
|
specialRouteFragmentClassMap.put("invites", InvitesFragment.class);
|
||||||
specialRouteFragmentClassMap.put("library", LibraryFragment.class);
|
specialRouteFragmentClassMap.put("library", LibraryFragment.class);
|
||||||
//specialRouteFragmentClassMap.put("publish", PublishFragment.class);
|
specialRouteFragmentClassMap.put("publish", PublishFragment.class);
|
||||||
//specialRouteFragmentClassMap.put("publishes", PublishesFragment.class);
|
specialRouteFragmentClassMap.put("publishes", PublishesFragment.class);
|
||||||
specialRouteFragmentClassMap.put("following", FollowingFragment.class);
|
specialRouteFragmentClassMap.put("following", FollowingFragment.class);
|
||||||
specialRouteFragmentClassMap.put("rewards", RewardsFragment.class);
|
specialRouteFragmentClassMap.put("rewards", RewardsFragment.class);
|
||||||
specialRouteFragmentClassMap.put("settings", SettingsFragment.class);
|
specialRouteFragmentClassMap.put("settings", SettingsFragment.class);
|
||||||
|
@ -512,6 +495,16 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
checkNotificationOpenIntent(intent);
|
checkNotificationOpenIntent(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addCameraPermissionListener(CameraPermissionListener listener) {
|
||||||
|
if (!cameraPermissionListeners.contains(listener)) {
|
||||||
|
cameraPermissionListeners.add(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeCameraPermissionListener(CameraPermissionListener listener) {
|
||||||
|
cameraPermissionListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
public void addDownloadActionListener(DownloadActionListener listener) {
|
public void addDownloadActionListener(DownloadActionListener listener) {
|
||||||
if (!downloadActionListeners.contains(listener)) {
|
if (!downloadActionListeners.contains(listener)) {
|
||||||
downloadActionListeners.add(listener);
|
downloadActionListeners.add(listener);
|
||||||
|
@ -581,12 +574,18 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
openFragment(AllContentFragment.class, true, NavMenuItem.ID_ITEM_ALL_CONTENT);
|
openFragment(AllContentFragment.class, true, NavMenuItem.ID_ITEM_ALL_CONTENT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NavMenuItem.ID_ITEM_NEW_PUBLISH:
|
||||||
|
openFragment(PublishFragment.class, true, NavMenuItem.ID_ITEM_NEW_PUBLISH);
|
||||||
|
break;
|
||||||
case NavMenuItem.ID_ITEM_CHANNELS:
|
case NavMenuItem.ID_ITEM_CHANNELS:
|
||||||
openFragment(ChannelManagerFragment.class, true, NavMenuItem.ID_ITEM_CHANNELS);
|
openFragment(ChannelManagerFragment.class, true, NavMenuItem.ID_ITEM_CHANNELS);
|
||||||
break;
|
break;
|
||||||
case NavMenuItem.ID_ITEM_LIBRARY:
|
case NavMenuItem.ID_ITEM_LIBRARY:
|
||||||
openFragment(LibraryFragment.class, true, NavMenuItem.ID_ITEM_LIBRARY);
|
openFragment(LibraryFragment.class, true, NavMenuItem.ID_ITEM_LIBRARY);
|
||||||
break;
|
break;
|
||||||
|
case NavMenuItem.ID_ITEM_PUBLISHES:
|
||||||
|
openFragment(PublishesFragment.class, true, NavMenuItem.ID_ITEM_PUBLISHES);
|
||||||
|
break;
|
||||||
|
|
||||||
case NavMenuItem.ID_ITEM_WALLET:
|
case NavMenuItem.ID_ITEM_WALLET:
|
||||||
openFragment(WalletFragment.class, true, NavMenuItem.ID_ITEM_WALLET);
|
openFragment(WalletFragment.class, true, NavMenuItem.ID_ITEM_WALLET);
|
||||||
|
@ -818,6 +817,20 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void suspendGlobalPlayer(Context context) {
|
||||||
|
if (MainActivity.appPlayer != null) {
|
||||||
|
MainActivity.appPlayer.setPlayWhenReady(false);
|
||||||
|
}
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
((MainActivity) context).hideGlobalNowPlaying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void resumeGlobalPlayer(Context context) {
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
((MainActivity) context).checkNowPlaying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void toggleUrlSuggestions(boolean visible) {
|
private void toggleUrlSuggestions(boolean visible) {
|
||||||
View container = findViewById(R.id.url_suggestions_container);
|
View container = findViewById(R.id.url_suggestions_container);
|
||||||
View closeIcon = findViewById(R.id.wunderbar_close);
|
View closeIcon = findViewById(R.id.wunderbar_close);
|
||||||
|
@ -830,7 +843,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
|
|
||||||
public int getScaledValue(int value) {
|
public int getScaledValue(int value) {
|
||||||
float scale = getResources().getDisplayMetrics().density;
|
float scale = getResources().getDisplayMetrics().density;
|
||||||
return (int) (value * scale + 0.5f);
|
return Helper.getScaledValue(value, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupUriBar() {
|
private void setupUriBar() {
|
||||||
|
@ -1249,6 +1262,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
startup();
|
startup();
|
||||||
} else if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
|
} else if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
|
||||||
openFragment(FollowingFragment.class, false, NavMenuItem.ID_ITEM_FOLLOWING);
|
openFragment(FollowingFragment.class, false, NavMenuItem.ID_ITEM_FOLLOWING);
|
||||||
|
fetchRewards();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1340,7 +1354,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
if (navMenuAdapter != null) {
|
if (navMenuAdapter != null) {
|
||||||
navMenuAdapter.setExtraLabelForItem(
|
navMenuAdapter.setExtraLabelForItem(
|
||||||
NavMenuItem.ID_ITEM_WALLET,
|
NavMenuItem.ID_ITEM_WALLET,
|
||||||
Lbryio.LBCUSDRate > 0 ? String.format("$%s", Helper.USD_CURRENCY_FORMAT.format(usdBalance)) : null
|
Lbryio.LBCUSDRate > 0 ? String.format("$%s", Helper.SIMPLE_CURRENCY_FORMAT.format(usdBalance)) : null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1750,9 +1764,21 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
listener.onStoragePermissionRefused();
|
listener.onStoragePermissionRefused();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
startingStoragePermissionRequest = false;
|
startingPermissionRequest = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case REQUEST_CAMERA_PERMISSION:
|
||||||
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
for (CameraPermissionListener listener : cameraPermissionListeners) {
|
||||||
|
listener.onCameraPermissionGranted();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (CameraPermissionListener listener : cameraPermissionListeners) {
|
||||||
|
listener.onCameraPermissionRefused();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startingPermissionRequest = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2015,7 +2041,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
if (navMenuAdapter != null) {
|
if (navMenuAdapter != null) {
|
||||||
navMenuAdapter.setExtraLabelForItem(
|
navMenuAdapter.setExtraLabelForItem(
|
||||||
NavMenuItem.ID_ITEM_REWARDS,
|
NavMenuItem.ID_ITEM_REWARDS,
|
||||||
Lbryio.LBCUSDRate > 0 ? String.format("$%s", Helper.USD_CURRENCY_FORMAT.format(usdRewardAmount)) : null
|
Lbryio.LBCUSDRate > 0 ? String.format("$%s", Helper.SIMPLE_CURRENCY_FORMAT.format(usdRewardAmount)) : null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2115,7 +2141,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
}, 1000);
|
}, 1000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (startingStoragePermissionRequest) {
|
if (startingPermissionRequest) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
enterPIPMode();
|
enterPIPMode();
|
||||||
|
@ -2241,10 +2267,10 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
));
|
));
|
||||||
|
|
||||||
yourContentGroup.setItems(Arrays.asList(
|
yourContentGroup.setItems(Arrays.asList(
|
||||||
//new NavMenuItem(NavMenuItem.ID_ITEM_NEW_PUBLISH, R.string.fa_upload, R.string.new_publish, "NewPublish", context),
|
new NavMenuItem(NavMenuItem.ID_ITEM_NEW_PUBLISH, R.string.fa_upload, R.string.new_publish, "NewPublish", context),
|
||||||
new NavMenuItem(NavMenuItem.ID_ITEM_CHANNELS, R.string.fa_at, R.string.channels, "Channels", context),
|
new NavMenuItem(NavMenuItem.ID_ITEM_CHANNELS, R.string.fa_at, R.string.channels, "Channels", context),
|
||||||
new NavMenuItem(NavMenuItem.ID_ITEM_LIBRARY, R.string.fa_download, R.string.library, "Library", context)
|
new NavMenuItem(NavMenuItem.ID_ITEM_LIBRARY, R.string.fa_download, R.string.library, "Library", context),
|
||||||
//new NavMenuItem(NavMenuItem.ID_ITEM_PUBLISHES, R.string.fa_cloud_upload, R.string.publishes, "Publishes", context)
|
new NavMenuItem(NavMenuItem.ID_ITEM_PUBLISHES, R.string.fa_cloud_upload, R.string.publishes, "Publishes", context)
|
||||||
));
|
));
|
||||||
|
|
||||||
walletGroup.setItems(Arrays.asList(
|
walletGroup.setItems(Arrays.asList(
|
||||||
|
@ -2518,7 +2544,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
if (!forceRequest && ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, permission)) {
|
if (!forceRequest && ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, permission)) {
|
||||||
Toast.makeText(context, rationale, Toast.LENGTH_LONG).show();
|
Toast.makeText(context, rationale, Toast.LENGTH_LONG).show();
|
||||||
} else {
|
} else {
|
||||||
startingStoragePermissionRequest = true;
|
startingPermissionRequest = true;
|
||||||
ActivityCompat.requestPermissions((Activity) context, new String[] { permission }, requestCode);
|
ActivityCompat.requestPermissions((Activity) context, new String[] { permission }, requestCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,14 @@ public class ClaimListAdapter extends RecyclerView.Adapter<ClaimListAdapter.View
|
||||||
return new ArrayList<>(this.items);
|
return new ArrayList<>(this.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateSigningChannelForClaim(Claim resolvedClaim) {
|
||||||
|
for (Claim claim : items) {
|
||||||
|
if (claim.getClaimId().equalsIgnoreCase(resolvedClaim.getClaimId())) {
|
||||||
|
claim.setSigningChannel(resolvedClaim.getSigningChannel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void clearItems() {
|
public void clearItems() {
|
||||||
clearSelectedItems();
|
clearSelectedItems();
|
||||||
this.items.clear();
|
this.items.clear();
|
||||||
|
@ -413,7 +421,10 @@ public class ClaimListAdapter extends RecyclerView.Adapter<ClaimListAdapter.View
|
||||||
boolean isDownloading = false;
|
boolean isDownloading = false;
|
||||||
int progress = 0;
|
int progress = 0;
|
||||||
String fileSizeString = claimFile == null ? null : Helper.formatBytes(claimFile.getTotalBytes(), false);
|
String fileSizeString = claimFile == null ? null : Helper.formatBytes(claimFile.getTotalBytes(), false);
|
||||||
if (claimFile != null && !claimFile.isCompleted() && claimFile.getWrittenBytes() < claimFile.getTotalBytes()) {
|
if (claimFile != null &&
|
||||||
|
!Helper.isNullOrEmpty(claimFile.getDownloadPath()) &&
|
||||||
|
!claimFile.isCompleted() &&
|
||||||
|
claimFile.getWrittenBytes() < claimFile.getTotalBytes()) {
|
||||||
isDownloading = true;
|
isDownloading = true;
|
||||||
progress = claimFile.getTotalBytes() > 0 ?
|
progress = claimFile.getTotalBytes() > 0 ?
|
||||||
Double.valueOf(((double) claimFile.getWrittenBytes() / (double) claimFile.getTotalBytes()) * 100.0).intValue() : 0;
|
Double.valueOf(((double) claimFile.getWrittenBytes() / (double) claimFile.getTotalBytes()) * 100.0).intValue() : 0;
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
package io.lbry.browser.adapter;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.lbry.browser.R;
|
||||||
|
import io.lbry.browser.listener.ChannelItemSelectionListener;
|
||||||
|
import io.lbry.browser.model.Claim;
|
||||||
|
import io.lbry.browser.model.GalleryItem;
|
||||||
|
import io.lbry.browser.utils.Helper;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
public class GalleryGridAdapter extends RecyclerView.Adapter<GalleryGridAdapter.ViewHolder> {
|
||||||
|
private Context context;
|
||||||
|
private List<GalleryItem> items;
|
||||||
|
@Setter
|
||||||
|
private GalleryItemClickListener listener;
|
||||||
|
|
||||||
|
public GalleryGridAdapter(List<GalleryItem> items, Context context) {
|
||||||
|
this.items = new ArrayList<>(items);
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
protected ImageView thumbnailView;
|
||||||
|
protected TextView durationView;
|
||||||
|
public ViewHolder(View v) {
|
||||||
|
super(v);
|
||||||
|
thumbnailView = v.findViewById(R.id.gallery_item_thumbnail);
|
||||||
|
durationView = v.findViewById(R.id.gallery_item_duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getItemCount() {
|
||||||
|
return items != null ? items.size() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItem(GalleryItem item) {
|
||||||
|
if (!items.contains(item)) {
|
||||||
|
items.add(item);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItems(List<GalleryItem> items) {
|
||||||
|
for (GalleryItem item : items) {
|
||||||
|
if (!this.items.contains(item)) {
|
||||||
|
this.items.add(item);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearItems() {
|
||||||
|
items.clear();
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GalleryGridAdapter.ViewHolder onCreateViewHolder(ViewGroup root, int viewType) {
|
||||||
|
View v = LayoutInflater.from(context).inflate(R.layout.list_item_gallery, root, false);
|
||||||
|
return new GalleryGridAdapter.ViewHolder(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(GalleryGridAdapter.ViewHolder vh, int position) {
|
||||||
|
GalleryItem item = items.get(position);
|
||||||
|
String thumbnailUrl = item.getThumbnailUrl();
|
||||||
|
Glide.with(context.getApplicationContext()).load(thumbnailUrl).centerCrop().into(vh.thumbnailView);
|
||||||
|
vh.durationView.setVisibility(item.getDuration() > 0 ? View.VISIBLE : View.INVISIBLE);
|
||||||
|
vh.durationView.setText(item.getDuration() > 0 ? Helper.formatDuration(Double.valueOf(item.getDuration() / 1000.0).longValue()) : null);
|
||||||
|
|
||||||
|
vh.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onGalleryItemClicked(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface GalleryItemClickListener {
|
||||||
|
void onGalleryItemClicked(GalleryItem item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GalleryGridItemDecoration extends RecyclerView.ItemDecoration {
|
||||||
|
|
||||||
|
private int spanCount;
|
||||||
|
private int spacing;
|
||||||
|
|
||||||
|
public GalleryGridItemDecoration(int spanCount, int spacing) {
|
||||||
|
this.spanCount = spanCount;
|
||||||
|
this.spacing = spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||||
|
int position = parent.getChildAdapterPosition(view); // item position
|
||||||
|
int column = position % spanCount; // item column
|
||||||
|
|
||||||
|
outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
|
||||||
|
outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing)
|
||||||
|
if (position >= spanCount) {
|
||||||
|
outRect.top = spacing; // item top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -159,7 +159,7 @@ public class RewardListAdapter extends RecyclerView.Adapter<RewardListAdapter.Vi
|
||||||
});
|
});
|
||||||
|
|
||||||
vh.textUsdValue.setText(reward.isCustom() || Lbryio.LBCUSDRate == 0 ? null :
|
vh.textUsdValue.setText(reward.isCustom() || Lbryio.LBCUSDRate == 0 ? null :
|
||||||
String.format("≈$%s", Helper.USD_CURRENCY_FORMAT.format(rewardAmount * Lbryio.LBCUSDRate)));
|
String.format("≈$%s", Helper.SIMPLE_CURRENCY_FORMAT.format(rewardAmount * Lbryio.LBCUSDRate)));
|
||||||
|
|
||||||
vh.itemView.setOnClickListener(new View.OnClickListener() {
|
vh.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,7 +22,7 @@ import io.lbry.browser.utils.Helper;
|
||||||
import io.lbry.browser.utils.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
|
|
||||||
public class DatabaseHelper extends SQLiteOpenHelper {
|
public class DatabaseHelper extends SQLiteOpenHelper {
|
||||||
public static final int DATABASE_VERSION = 1;
|
public static final int DATABASE_VERSION = 2;
|
||||||
public static final String DATABASE_NAME = "LbryApp.db";
|
public static final String DATABASE_NAME = "LbryApp.db";
|
||||||
private static DatabaseHelper instance;
|
private static DatabaseHelper instance;
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||||
", claim_id TEXT" +
|
", claim_id TEXT" +
|
||||||
", claim_name TEXT" +
|
", claim_name TEXT" +
|
||||||
", cost REAL " +
|
", cost REAL " +
|
||||||
|
", currency TEXT " +
|
||||||
", title TEXT " +
|
", title TEXT " +
|
||||||
", publisher_claim_id TEXT" +
|
", publisher_claim_id TEXT" +
|
||||||
", publisher_name TEXT" +
|
", publisher_name TEXT" +
|
||||||
|
@ -58,6 +59,10 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||||
"CREATE INDEX idx_view_history_device ON view_history (device)"
|
"CREATE INDEX idx_view_history_device ON view_history (device)"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final String[] SQL_V1_V2_UPGRADE = {
|
||||||
|
"ALTER TABLE view_history ADD COLUMN currency TEXT"
|
||||||
|
};
|
||||||
|
|
||||||
private static final String SQL_INSERT_SUBSCRIPTION = "REPLACE INTO subscriptions (channel_name, url) VALUES (?, ?)";
|
private static final String SQL_INSERT_SUBSCRIPTION = "REPLACE INTO subscriptions (channel_name, url) VALUES (?, ?)";
|
||||||
private static final String SQL_DELETE_SUBSCRIPTION = "DELETE FROM subscriptions WHERE url = ?";
|
private static final String SQL_DELETE_SUBSCRIPTION = "DELETE FROM subscriptions WHERE url = ?";
|
||||||
private static final String SQL_GET_SUBSCRIPTIONS = "SELECT channel_name, url FROM subscriptions";
|
private static final String SQL_GET_SUBSCRIPTIONS = "SELECT channel_name, url FROM subscriptions";
|
||||||
|
@ -68,9 +73,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||||
private static final String SQL_GET_RECENT_URL_HISTORY = "SELECT value, url, type FROM url_history ORDER BY timestamp DESC LIMIT 10";
|
private static final String SQL_GET_RECENT_URL_HISTORY = "SELECT value, url, type FROM url_history ORDER BY timestamp DESC LIMIT 10";
|
||||||
|
|
||||||
private static final String SQL_INSERT_VIEW_HISTORY =
|
private static final String SQL_INSERT_VIEW_HISTORY =
|
||||||
"REPLACE INTO view_history (url, claim_id, claim_name, cost, title, publisher_claim_id, publisher_name, publisher_title, thumbnail_url, device, release_time, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
"REPLACE INTO view_history (url, claim_id, claim_name, cost, currency, title, publisher_claim_id, publisher_name, publisher_title, thumbnail_url, device, release_time, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
private static final String SQL_GET_VIEW_HISTORY =
|
private static final String SQL_GET_VIEW_HISTORY =
|
||||||
"SELECT url, claim_id, claim_name, cost, title, publisher_claim_id, publisher_name, publisher_title, thumbnail_url, device, release_time, timestamp " +
|
"SELECT url, claim_id, claim_name, cost, currency, title, publisher_claim_id, publisher_name, publisher_title, thumbnail_url, device, release_time, timestamp " +
|
||||||
"FROM view_history WHERE '' = ? OR timestamp < ? ORDER BY timestamp DESC LIMIT %d";
|
"FROM view_history WHERE '' = ? OR timestamp < ? ORDER BY timestamp DESC LIMIT %d";
|
||||||
private static final String SQL_CLEAR_VIEW_HISTORY = "DELETE FROM view_history";
|
private static final String SQL_CLEAR_VIEW_HISTORY = "DELETE FROM view_history";
|
||||||
private static final String SQL_CLEAR_VIEW_HISTORY_BY_DEVICE = "DELETE FROM view_history WHERE device = ?";
|
private static final String SQL_CLEAR_VIEW_HISTORY_BY_DEVICE = "DELETE FROM view_history WHERE device = ?";
|
||||||
|
@ -82,6 +87,8 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||||
private static final String SQL_UNFOLLOW_TAGS = "UPDATE tags SET is_followed = 0";
|
private static final String SQL_UNFOLLOW_TAGS = "UPDATE tags SET is_followed = 0";
|
||||||
private static final String SQL_GET_FOLLOWED_TAGS = "SELECT name FROM tags WHERE is_followed = 1";
|
private static final String SQL_GET_FOLLOWED_TAGS = "SELECT name FROM tags WHERE is_followed = 1";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public DatabaseHelper(Context context) {
|
public DatabaseHelper(Context context) {
|
||||||
super(context, String.format("%s/%s", context.getFilesDir().getAbsolutePath(), DATABASE_NAME), null, DATABASE_VERSION);
|
super(context, String.format("%s/%s", context.getFilesDir().getAbsolutePath(), DATABASE_NAME), null, DATABASE_VERSION);
|
||||||
instance = this;
|
instance = this;
|
||||||
|
@ -98,7 +105,11 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
|
if (oldVersion < 2) {
|
||||||
|
for (String sql : SQL_V1_V2_UPGRADE) {
|
||||||
|
db.execSQL(sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
|
|
||||||
|
@ -142,6 +153,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||||
viewHistory.getClaimId(),
|
viewHistory.getClaimId(),
|
||||||
viewHistory.getClaimName(),
|
viewHistory.getClaimName(),
|
||||||
viewHistory.getCost() != null ? viewHistory.getCost().doubleValue() : 0,
|
viewHistory.getCost() != null ? viewHistory.getCost().doubleValue() : 0,
|
||||||
|
viewHistory.getCurrency(),
|
||||||
viewHistory.getTitle(),
|
viewHistory.getTitle(),
|
||||||
viewHistory.getPublisherClaimId(),
|
viewHistory.getPublisherClaimId(),
|
||||||
viewHistory.getPublisherName(),
|
viewHistory.getPublisherName(),
|
||||||
|
@ -166,6 +178,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||||
item.setClaimId(cursor.getString(cursorIndex++));
|
item.setClaimId(cursor.getString(cursorIndex++));
|
||||||
item.setClaimName(cursor.getString(cursorIndex++));
|
item.setClaimName(cursor.getString(cursorIndex++));
|
||||||
item.setCost(new BigDecimal(cursor.getDouble(cursorIndex++)));
|
item.setCost(new BigDecimal(cursor.getDouble(cursorIndex++)));
|
||||||
|
item.setCurrency(cursor.getString(cursorIndex++));
|
||||||
item.setTitle(cursor.getString(cursorIndex++));
|
item.setTitle(cursor.getString(cursorIndex++));
|
||||||
item.setPublisherClaimId(cursor.getString(cursorIndex++));
|
item.setPublisherClaimId(cursor.getString(cursorIndex++));
|
||||||
item.setPublisherName(cursor.getString(cursorIndex++));
|
item.setPublisherName(cursor.getString(cursorIndex++));
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package io.lbry.browser.listener;
|
||||||
|
|
||||||
|
public interface CameraPermissionListener {
|
||||||
|
void onCameraPermissionGranted();
|
||||||
|
void onCameraPermissionRefused();
|
||||||
|
void onRecordAudioPermissionGranted();
|
||||||
|
void onRecordAudioPermissionRefused();
|
||||||
|
}
|
13
app/src/main/java/io/lbry/browser/model/GalleryItem.java
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package io.lbry.browser.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class GalleryItem {
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String filePath;
|
||||||
|
private String type;
|
||||||
|
private String thumbnailUrl;
|
||||||
|
private long duration;
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -18,13 +19,16 @@ import io.lbry.browser.utils.Helper;
|
||||||
import io.lbry.browser.utils.Lbry;
|
import io.lbry.browser.utils.Lbry;
|
||||||
|
|
||||||
public class ClaimListTask extends AsyncTask<Void, Void, List<Claim>> {
|
public class ClaimListTask extends AsyncTask<Void, Void, List<Claim>> {
|
||||||
private String type;
|
private List<String> types;
|
||||||
private View progressView;
|
private View progressView;
|
||||||
private ClaimListResultHandler handler;
|
private ClaimListResultHandler handler;
|
||||||
private Exception error;
|
private Exception error;
|
||||||
|
|
||||||
public ClaimListTask(String type, View progressView, ClaimListResultHandler handler) {
|
public ClaimListTask(String type, View progressView, ClaimListResultHandler handler) {
|
||||||
this.type = type;
|
this(Arrays.asList(type), progressView, handler);
|
||||||
|
}
|
||||||
|
public ClaimListTask(List<String> types, View progressView, ClaimListResultHandler handler) {
|
||||||
|
this.types = types;
|
||||||
this.progressView = progressView;
|
this.progressView = progressView;
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
}
|
}
|
||||||
|
@ -36,8 +40,8 @@ public class ClaimListTask extends AsyncTask<Void, Void, List<Claim>> {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Map<String, Object> options = new HashMap<>();
|
Map<String, Object> options = new HashMap<>();
|
||||||
if (!Helper.isNullOrEmpty(type)) {
|
if (types != null && types.size() > 0) {
|
||||||
options.put("claim_type", type);
|
options.put("claim_type", types);
|
||||||
}
|
}
|
||||||
options.put("page", 1);
|
options.put("page", 1);
|
||||||
options.put("page_size", 999);
|
options.put("page_size", 999);
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
package io.lbry.browser.tasks.localdata;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.sqlite.SQLiteException;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.lbry.browser.model.GalleryItem;
|
||||||
|
import io.lbry.browser.utils.Helper;
|
||||||
|
|
||||||
|
public class LoadGalleryItemsTask extends AsyncTask<Void, GalleryItem, List<GalleryItem>> {
|
||||||
|
private static final String TAG = "LoadGalleryItemsTask";
|
||||||
|
private LoadGalleryHandler handler;
|
||||||
|
private View progressView;
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
public LoadGalleryItemsTask(View progressView, Context context, LoadGalleryHandler handler) {
|
||||||
|
this.progressView = progressView;
|
||||||
|
this.context = context;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onPreExecute(Void... params) {
|
||||||
|
Helper.setViewVisibility(progressView, View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<GalleryItem> doInBackground(Void... params) {
|
||||||
|
List<GalleryItem> items = new ArrayList<>();
|
||||||
|
List<GalleryItem> itemsWithThumbnails = new ArrayList<>();
|
||||||
|
Cursor cursor = null;
|
||||||
|
if (context != null) {
|
||||||
|
ContentResolver resolver = context.getContentResolver();
|
||||||
|
try {
|
||||||
|
String[] projection = {
|
||||||
|
MediaStore.MediaColumns._ID,
|
||||||
|
MediaStore.MediaColumns.DATA,
|
||||||
|
MediaStore.MediaColumns.DISPLAY_NAME,
|
||||||
|
MediaStore.MediaColumns.MIME_TYPE,
|
||||||
|
MediaStore.Video.Media.DURATION
|
||||||
|
};
|
||||||
|
cursor = resolver.query(
|
||||||
|
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
|
||||||
|
projection, null, null,
|
||||||
|
String.format("%s DESC", MediaStore.MediaColumns.DATE_MODIFIED));
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
int idColumn = cursor.getColumnIndex(MediaStore.MediaColumns._ID);
|
||||||
|
int nameColumn = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
|
||||||
|
int typeColumn = cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE);
|
||||||
|
int pathColumn = cursor.getColumnIndex(MediaStore.MediaColumns.DATA);
|
||||||
|
int durationColumn = cursor.getColumnIndex(MediaStore.Video.Media.DURATION);
|
||||||
|
|
||||||
|
String id = cursor.getString(idColumn);
|
||||||
|
GalleryItem item = new GalleryItem();
|
||||||
|
item.setId(id);
|
||||||
|
item.setName(cursor.getString(nameColumn));
|
||||||
|
item.setType(cursor.getString(typeColumn));
|
||||||
|
item.setFilePath(cursor.getString(pathColumn));
|
||||||
|
item.setDuration(cursor.getLong(durationColumn));
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
} catch (SQLiteException ex) {
|
||||||
|
|
||||||
|
// failed to load videos. log and pass
|
||||||
|
Log.e(TAG, ex.getMessage(), ex);
|
||||||
|
} finally {
|
||||||
|
Helper.closeCursor(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load (or generate) thumbnail for each item
|
||||||
|
for (GalleryItem item : items) {
|
||||||
|
String id = item.getId();
|
||||||
|
File cacheDir = context.getExternalCacheDir();
|
||||||
|
File thumbnailsDir = new File(String.format("%s/thumbnails", cacheDir.getAbsolutePath()));
|
||||||
|
if (!thumbnailsDir.isDirectory()) {
|
||||||
|
thumbnailsDir.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
String thumbnailPath = String.format("%s/%s.png", thumbnailsDir.getAbsolutePath(), id);
|
||||||
|
File file = new File(thumbnailPath);
|
||||||
|
if (!file.exists()) {
|
||||||
|
// save the thumbnail to the path
|
||||||
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||||
|
options.inSampleSize = 1;
|
||||||
|
Bitmap thumbnail = MediaStore.Video.Thumbnails.getThumbnail(
|
||||||
|
resolver, Long.parseLong(id), MediaStore.Video.Thumbnails.MINI_KIND, options);
|
||||||
|
if (thumbnail != null) {
|
||||||
|
try (FileOutputStream os = new FileOutputStream(thumbnailPath)) {
|
||||||
|
thumbnail.compress(Bitmap.CompressFormat.PNG, 80, os);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
// skip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.exists() && file.length() > 0) {
|
||||||
|
item.setThumbnailUrl(Uri.fromFile(file).toString());
|
||||||
|
itemsWithThumbnails.add(item);
|
||||||
|
publishProgress(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemsWithThumbnails;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onProgressUpdate(GalleryItem... items) {
|
||||||
|
if (handler != null) {
|
||||||
|
for (GalleryItem item : items) {
|
||||||
|
handler.onItemLoaded(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onPostExecute(List<GalleryItem> items) {
|
||||||
|
if (handler != null) {
|
||||||
|
handler.onAllItemsLoaded(items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface LoadGalleryHandler {
|
||||||
|
void onItemLoaded(GalleryItem item);
|
||||||
|
void onAllItemsLoaded(List<GalleryItem> items);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,34 @@ public class BaseFragment extends Fragment {
|
||||||
@Setter
|
@Setter
|
||||||
private Map<String, Object> params;
|
private Map<String, Object> params;
|
||||||
|
|
||||||
|
public boolean shouldHideGlobalPlayer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldSuspendGlobalPlayer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
if (shouldSuspendGlobalPlayer()) {
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity.suspendGlobalPlayer(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onStop() {
|
||||||
|
if (shouldSuspendGlobalPlayer()) {
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity.resumeGlobalPlayer(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onStop();
|
||||||
|
}
|
||||||
|
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
|
@ -23,12 +51,11 @@ public class BaseFragment extends Fragment {
|
||||||
MainActivity activity = (MainActivity) context;
|
MainActivity activity = (MainActivity) context;
|
||||||
activity.setSelectedMenuItemForFragment(this);
|
activity.setSelectedMenuItemForFragment(this);
|
||||||
|
|
||||||
if (this instanceof FileViewFragment) {
|
if (shouldHideGlobalPlayer()) {
|
||||||
activity.hideGlobalNowPlaying();
|
activity.hideGlobalNowPlaying();
|
||||||
} else {
|
} else {
|
||||||
activity.checkNowPlaying();
|
activity.checkNowPlaying();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,7 @@ public class ChannelContentFragment extends Fragment implements DownloadActionLi
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
boolean canShowMatureContent = false;
|
boolean canShowMatureContent = false;
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
canShowMatureContent = sp.getBoolean(MainActivity.PREFERENCE_KEY_SHOW_MATURE_CONTENT, false);
|
canShowMatureContent = sp.getBoolean(MainActivity.PREFERENCE_KEY_SHOW_MATURE_CONTENT, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -936,20 +936,22 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
loadViewCount();
|
loadViewCount();
|
||||||
checkIsFollowing();
|
checkIsFollowing();
|
||||||
|
|
||||||
getView().findViewById(R.id.file_view_scroll_view).scrollTo(0, 0);
|
View root = getView();
|
||||||
|
if (root != null) {
|
||||||
|
root.findViewById(R.id.file_view_scroll_view).scrollTo(0, 0);
|
||||||
Helper.setViewVisibility(layoutDisplayArea, View.VISIBLE);
|
Helper.setViewVisibility(layoutDisplayArea, View.VISIBLE);
|
||||||
|
|
||||||
ImageView descIndicator = getView().findViewById(R.id.file_view_desc_toggle_arrow);
|
ImageView descIndicator = root.findViewById(R.id.file_view_desc_toggle_arrow);
|
||||||
descIndicator.setImageResource(R.drawable.ic_arrow_dropdown);
|
descIndicator.setImageResource(R.drawable.ic_arrow_dropdown);
|
||||||
|
|
||||||
getView().findViewById(R.id.file_view_description_area).setVisibility(View.GONE);
|
root.findViewById(R.id.file_view_description_area).setVisibility(View.GONE);
|
||||||
((TextView) getView().findViewById(R.id.file_view_title)).setText(claim.getTitle());
|
((TextView) root.findViewById(R.id.file_view_title)).setText(claim.getTitle());
|
||||||
((TextView) getView().findViewById(R.id.file_view_description)).setText(claim.getDescription());
|
((TextView) root.findViewById(R.id.file_view_description)).setText(claim.getDescription());
|
||||||
((TextView) getView().findViewById(R.id.file_view_publisher_name)).setText(
|
((TextView) root.findViewById(R.id.file_view_publisher_name)).setText(
|
||||||
Helper.isNullOrEmpty(claim.getPublisherName()) ? getString(R.string.anonymous) : claim.getPublisherName());
|
Helper.isNullOrEmpty(claim.getPublisherName()) ? getString(R.string.anonymous) : claim.getPublisherName());
|
||||||
|
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
RecyclerView descTagsList = getView().findViewById(R.id.file_view_tag_list);
|
RecyclerView descTagsList = root.findViewById(R.id.file_view_tag_list);
|
||||||
FlexboxLayoutManager flm = new FlexboxLayoutManager(context);
|
FlexboxLayoutManager flm = new FlexboxLayoutManager(context);
|
||||||
descTagsList.setLayoutManager(flm);
|
descTagsList.setLayoutManager(flm);
|
||||||
|
|
||||||
|
@ -967,27 +969,27 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
descTagsList.setAdapter(tagListAdapter);
|
descTagsList.setAdapter(tagListAdapter);
|
||||||
getView().findViewById(R.id.file_view_tag_area).setVisibility(tags.size() > 0 ? View.VISIBLE : View.GONE);
|
root.findViewById(R.id.file_view_tag_area).setVisibility(tags.size() > 0 ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
getView().findViewById(R.id.file_view_exoplayer_container).setVisibility(View.GONE);
|
root.findViewById(R.id.file_view_exoplayer_container).setVisibility(View.GONE);
|
||||||
getView().findViewById(R.id.file_view_unsupported_container).setVisibility(View.GONE);
|
root.findViewById(R.id.file_view_unsupported_container).setVisibility(View.GONE);
|
||||||
getView().findViewById(R.id.file_view_media_meta_container).setVisibility(View.VISIBLE);
|
root.findViewById(R.id.file_view_media_meta_container).setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
Claim.GenericMetadata metadata = claim.getValue();
|
Claim.GenericMetadata metadata = claim.getValue();
|
||||||
if (!Helper.isNullOrEmpty(claim.getThumbnailUrl())) {
|
if (!Helper.isNullOrEmpty(claim.getThumbnailUrl())) {
|
||||||
ImageView thumbnailView = getView().findViewById(R.id.file_view_thumbnail);
|
ImageView thumbnailView = root.findViewById(R.id.file_view_thumbnail);
|
||||||
Glide.with(getContext().getApplicationContext()).load(claim.getThumbnailUrl()).centerCrop().into(thumbnailView);
|
Glide.with(getContext().getApplicationContext()).load(claim.getThumbnailUrl()).centerCrop().into(thumbnailView);
|
||||||
} else {
|
} else {
|
||||||
// display first x letters of claim name, with random background
|
// display first x letters of claim name, with random background
|
||||||
}
|
}
|
||||||
|
|
||||||
getView().findViewById(R.id.file_view_main_action_button).setOnClickListener(new View.OnClickListener() {
|
root.findViewById(R.id.file_view_main_action_button).setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
onMainActionButtonClicked();
|
onMainActionButtonClicked();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
getView().findViewById(R.id.file_view_media_meta_container).setOnClickListener(new View.OnClickListener() {
|
root.findViewById(R.id.file_view_media_meta_container).setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
onMainActionButtonClicked();
|
onMainActionButtonClicked();
|
||||||
|
@ -997,20 +999,20 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
if (metadata instanceof Claim.StreamMetadata) {
|
if (metadata instanceof Claim.StreamMetadata) {
|
||||||
Claim.StreamMetadata streamMetadata = (Claim.StreamMetadata) metadata;
|
Claim.StreamMetadata streamMetadata = (Claim.StreamMetadata) metadata;
|
||||||
long publishTime = streamMetadata.getReleaseTime() > 0 ? streamMetadata.getReleaseTime() * 1000 : claim.getTimestamp() * 1000;
|
long publishTime = streamMetadata.getReleaseTime() > 0 ? streamMetadata.getReleaseTime() * 1000 : claim.getTimestamp() * 1000;
|
||||||
((TextView) getView().findViewById(R.id.file_view_publish_time)).setText(DateUtils.getRelativeTimeSpanString(
|
((TextView) root.findViewById(R.id.file_view_publish_time)).setText(DateUtils.getRelativeTimeSpanString(
|
||||||
publishTime, System.currentTimeMillis(), 0, DateUtils.FORMAT_ABBREV_RELATIVE));
|
publishTime, System.currentTimeMillis(), 0, DateUtils.FORMAT_ABBREV_RELATIVE));
|
||||||
|
|
||||||
Fee fee = streamMetadata.getFee();
|
Fee fee = streamMetadata.getFee();
|
||||||
if (fee != null && Helper.parseDouble(fee.getAmount(), 0) > 0) {
|
if (fee != null && Helper.parseDouble(fee.getAmount(), 0) > 0) {
|
||||||
getView().findViewById(R.id.file_view_fee_container).setVisibility(View.VISIBLE);
|
root.findViewById(R.id.file_view_fee_container).setVisibility(View.VISIBLE);
|
||||||
((TextView) getView().findViewById(R.id.file_view_fee)).setText(
|
((TextView) root.findViewById(R.id.file_view_fee)).setText(
|
||||||
Helper.shortCurrencyFormat(claim.getActualCost(Lbryio.LBCUSDRate).doubleValue()));
|
Helper.shortCurrencyFormat(claim.getActualCost(Lbryio.LBCUSDRate).doubleValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getView().findViewById(R.id.file_view_icon_follow_unfollow).setVisibility(claim.getSigningChannel() != null ? View.VISIBLE : View.GONE);
|
root.findViewById(R.id.file_view_icon_follow_unfollow).setVisibility(claim.getSigningChannel() != null ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
MaterialButton mainActionButton = getView().findViewById(R.id.file_view_main_action_button);
|
MaterialButton mainActionButton = root.findViewById(R.id.file_view_main_action_button);
|
||||||
if (claim.isPlayable()) {
|
if (claim.isPlayable()) {
|
||||||
mainActionButton.setText(R.string.play);
|
mainActionButton.setText(R.string.play);
|
||||||
} else if (claim.isViewable()) {
|
} else if (claim.isViewable()) {
|
||||||
|
@ -1037,11 +1039,12 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
restoreMainActionButton();
|
restoreMainActionButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
RecyclerView relatedContentList = getView().findViewById(R.id.file_view_related_content_list);
|
RecyclerView relatedContentList = root.findViewById(R.id.file_view_related_content_list);
|
||||||
if (relatedContentList == null || relatedContentList.getAdapter() == null || relatedContentList.getAdapter().getItemCount() == 0) {
|
if (relatedContentList == null || relatedContentList.getAdapter() == null || relatedContentList.getAdapter().getItemCount() == 0) {
|
||||||
loadRelatedContent();
|
loadRelatedContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void showUnsupportedView() {
|
private void showUnsupportedView() {
|
||||||
getView().findViewById(R.id.file_view_exoplayer_container).setVisibility(View.GONE);
|
getView().findViewById(R.id.file_view_exoplayer_container).setVisibility(View.GONE);
|
||||||
|
@ -1067,7 +1070,7 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
boolean newPlayerCreated = false;
|
boolean newPlayerCreated = false;
|
||||||
|
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
if (MainActivity.appPlayer == null) {
|
if (MainActivity.appPlayer == null && context != null) {
|
||||||
MainActivity.appPlayer = new SimpleExoPlayer.Builder(context).build();
|
MainActivity.appPlayer = new SimpleExoPlayer.Builder(context).build();
|
||||||
MainActivity.playerCache = new SimpleCache(context.getCacheDir(), new LeastRecentlyUsedCacheEvictor(1024 * 1024 * 256), new ExoDatabaseProvider(context));
|
MainActivity.playerCache = new SimpleCache(context.getCacheDir(), new LeastRecentlyUsedCacheEvictor(1024 * 1024 * 256), new ExoDatabaseProvider(context));
|
||||||
newPlayerCreated = true;
|
newPlayerCreated = true;
|
||||||
|
@ -1081,7 +1084,6 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
((MainActivity) context).getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
((MainActivity) context).getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (MainActivity.nowPlayingClaim != null &&
|
if (MainActivity.nowPlayingClaim != null &&
|
||||||
MainActivity.nowPlayingClaim.getClaimId().equalsIgnoreCase(claim.getClaimId()) &&
|
MainActivity.nowPlayingClaim.getClaimId().equalsIgnoreCase(claim.getClaimId()) &&
|
||||||
!newPlayerCreated) {
|
!newPlayerCreated) {
|
||||||
|
@ -1089,6 +1091,7 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MainActivity.appPlayer != null) {
|
||||||
showBuffering();
|
showBuffering();
|
||||||
if (fileViewPlayerListener != null) {
|
if (fileViewPlayerListener != null) {
|
||||||
MainActivity.appPlayer.addListener(fileViewPlayerListener);
|
MainActivity.appPlayer.addListener(fileViewPlayerListener);
|
||||||
|
@ -1107,6 +1110,7 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
|
|
||||||
MainActivity.appPlayer.prepare(mediaSource, true, true);
|
MainActivity.appPlayer.prepare(mediaSource, true, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setCurrentPlayer(Player currentPlayer) {
|
private void setCurrentPlayer(Player currentPlayer) {
|
||||||
if (this.currentPlayer == currentPlayer) {
|
if (this.currentPlayer == currentPlayer) {
|
||||||
|
@ -1174,9 +1178,12 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
public void onSuccess(int count) {
|
public void onSuccess(int count) {
|
||||||
try {
|
try {
|
||||||
String displayText = getResources().getQuantityString(R.plurals.view_count, count, NumberFormat.getInstance().format(count));
|
String displayText = getResources().getQuantityString(R.plurals.view_count, count, NumberFormat.getInstance().format(count));
|
||||||
TextView textViewCount = getView().findViewById(R.id.file_view_view_count);
|
View root = getView();
|
||||||
|
if (root != null) {
|
||||||
|
TextView textViewCount = root.findViewById(R.id.file_view_view_count);
|
||||||
Helper.setViewText(textViewCount, displayText);
|
Helper.setViewText(textViewCount, displayText);
|
||||||
Helper.setViewVisibility(textViewCount, View.VISIBLE);
|
Helper.setViewVisibility(textViewCount, View.VISIBLE);
|
||||||
|
}
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
// pass
|
// pass
|
||||||
}
|
}
|
||||||
|
@ -1218,7 +1225,12 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
if (claim != null) {
|
if (claim != null) {
|
||||||
Fee fee = ((Claim.StreamMetadata) claim.getValue()).getFee();
|
Fee fee = ((Claim.StreamMetadata) claim.getValue()).getFee();
|
||||||
double cost = claim.getActualCost(Lbryio.LBCUSDRate).doubleValue();
|
double cost = claim.getActualCost(Lbryio.LBCUSDRate).doubleValue();
|
||||||
String message = getResources().getQuantityString(R.plurals.confirm_purchase_message, cost == 1 ? 1 : 2, claim.getTitle(), cost);
|
String formattedCost = Helper.LBC_CURRENCY_FORMAT.format(cost);
|
||||||
|
String message = getResources().getQuantityString(
|
||||||
|
R.plurals.confirm_purchase_message,
|
||||||
|
cost == 1 ? 1 : 2,
|
||||||
|
claim.getTitle(),
|
||||||
|
formattedCost.equals("0") ? Helper.FULL_LBC_CURRENCY_FORMAT.format(cost) : formattedCost);
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()).
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()).
|
||||||
setTitle(R.string.confirm_purchase).
|
setTitle(R.string.confirm_purchase).
|
||||||
setMessage(message)
|
setMessage(message)
|
||||||
|
@ -1445,10 +1457,10 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showError(String message) {
|
public void showError(String message) {
|
||||||
Snackbar.make(getView().findViewById(R.id.file_view_claim_display_area), message, Snackbar.LENGTH_LONG).
|
View root = getView();
|
||||||
setTextColor(Color.WHITE).
|
if (root != null) {
|
||||||
setBackgroundTint(Color.RED).
|
Snackbar.make(root, message, Snackbar.LENGTH_LONG).setBackgroundTint(Color.RED).setTextColor(Color.WHITE).show();
|
||||||
show();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadRelatedContent() {
|
private void loadRelatedContent() {
|
||||||
|
@ -1884,4 +1896,9 @@ public class FileViewFragment extends BaseFragment implements
|
||||||
// invalid file info for download
|
// invalid file info for download
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldHideGlobalPlayer() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -396,8 +396,12 @@ public class FollowingFragment extends BaseFragment implements
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> buildSuggestedOptions() {
|
private Map<String, Object> buildSuggestedOptions() {
|
||||||
|
Context context = getContext();
|
||||||
|
boolean canShowMatureContent = false;
|
||||||
|
if (context != null) {
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||||
boolean canShowMatureContent = sp.getBoolean(MainActivity.PREFERENCE_KEY_SHOW_MATURE_CONTENT, false);
|
canShowMatureContent = sp.getBoolean(MainActivity.PREFERENCE_KEY_SHOW_MATURE_CONTENT, false);
|
||||||
|
}
|
||||||
|
|
||||||
return Lbry.buildClaimSearchOptions(
|
return Lbry.buildClaimSearchOptions(
|
||||||
Claim.TYPE_CHANNEL,
|
Claim.TYPE_CHANNEL,
|
||||||
|
|
|
@ -46,6 +46,8 @@ import io.lbry.browser.model.NavMenuItem;
|
||||||
import io.lbry.browser.model.ViewHistory;
|
import io.lbry.browser.model.ViewHistory;
|
||||||
import io.lbry.browser.tasks.claim.AbandonChannelTask;
|
import io.lbry.browser.tasks.claim.AbandonChannelTask;
|
||||||
import io.lbry.browser.tasks.claim.AbandonHandler;
|
import io.lbry.browser.tasks.claim.AbandonHandler;
|
||||||
|
import io.lbry.browser.tasks.claim.ClaimListResultHandler;
|
||||||
|
import io.lbry.browser.tasks.claim.ResolveTask;
|
||||||
import io.lbry.browser.tasks.file.BulkDeleteFilesTask;
|
import io.lbry.browser.tasks.file.BulkDeleteFilesTask;
|
||||||
import io.lbry.browser.tasks.file.DeleteFileTask;
|
import io.lbry.browser.tasks.file.DeleteFileTask;
|
||||||
import io.lbry.browser.tasks.file.FileListTask;
|
import io.lbry.browser.tasks.file.FileListTask;
|
||||||
|
@ -55,6 +57,7 @@ import io.lbry.browser.ui.channel.ChannelFormFragment;
|
||||||
import io.lbry.browser.utils.Helper;
|
import io.lbry.browser.utils.Helper;
|
||||||
import io.lbry.browser.utils.Lbry;
|
import io.lbry.browser.utils.Lbry;
|
||||||
import io.lbry.browser.utils.LbryAnalytics;
|
import io.lbry.browser.utils.LbryAnalytics;
|
||||||
|
import io.lbry.browser.utils.LbryUri;
|
||||||
|
|
||||||
public class LibraryFragment extends BaseFragment implements
|
public class LibraryFragment extends BaseFragment implements
|
||||||
ActionMode.Callback, DownloadActionListener, SelectionModeListener, SdkStatusListener {
|
ActionMode.Callback, DownloadActionListener, SelectionModeListener, SdkStatusListener {
|
||||||
|
@ -320,7 +323,10 @@ public class LibraryFragment extends BaseFragment implements
|
||||||
} else {
|
} else {
|
||||||
contentListAdapter.addItems(claims);
|
contentListAdapter.addItems(claims);
|
||||||
}
|
}
|
||||||
|
if (contentList.getAdapter() == null) {
|
||||||
contentList.setAdapter(contentListAdapter);
|
contentList.setAdapter(contentListAdapter);
|
||||||
|
}
|
||||||
|
resolveMissingChannelNames(buildUrlsToResolve(claims));
|
||||||
checkListEmpty();
|
checkListEmpty();
|
||||||
contentListLoading = false;
|
contentListLoading = false;
|
||||||
}
|
}
|
||||||
|
@ -355,7 +361,9 @@ public class LibraryFragment extends BaseFragment implements
|
||||||
} else {
|
} else {
|
||||||
contentListAdapter.addItems(claims);
|
contentListAdapter.addItems(claims);
|
||||||
}
|
}
|
||||||
|
if (contentList.getAdapter() == null) {
|
||||||
contentList.setAdapter(contentListAdapter);
|
contentList.setAdapter(contentListAdapter);
|
||||||
|
}
|
||||||
checkListEmpty();
|
checkListEmpty();
|
||||||
contentListLoading = false;
|
contentListLoading = false;
|
||||||
}
|
}
|
||||||
|
@ -564,6 +572,50 @@ public class LibraryFragment extends BaseFragment implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> buildUrlsToResolve(List<Claim> claims) {
|
||||||
|
List<String> urls = new ArrayList<>();
|
||||||
|
for (Claim claim : claims) {
|
||||||
|
Claim channel = claim.getSigningChannel();
|
||||||
|
if (channel != null && Helper.isNullOrEmpty(channel.getName()) && !Helper.isNullOrEmpty(channel.getClaimId())) {
|
||||||
|
LbryUri uri = LbryUri.tryParse(String.format("%s#%s", claim.getName(), claim.getClaimId()));
|
||||||
|
if (uri != null) {
|
||||||
|
urls.add(uri.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resolveMissingChannelNames(List<String> urls) {
|
||||||
|
if (urls.size() > 0) {
|
||||||
|
ResolveTask task = new ResolveTask(urls, Lbry.SDK_CONNECTION_STRING, null, new ClaimListResultHandler() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<Claim> claims) {
|
||||||
|
boolean updated = false;
|
||||||
|
for (Claim claim : claims) {
|
||||||
|
if (claim.getClaimId() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contentListAdapter != null) {
|
||||||
|
contentListAdapter.updateSigningChannelForClaim(claim);
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (updated) {
|
||||||
|
contentListAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void onEnterSelectionMode() {
|
public void onEnterSelectionMode() {
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
|
|
|
@ -0,0 +1,316 @@
|
||||||
|
package io.lbry.browser.ui.publish;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.camera.core.Camera;
|
||||||
|
import androidx.camera.core.CameraSelector;
|
||||||
|
import androidx.camera.core.CameraX;
|
||||||
|
import androidx.camera.core.Preview;
|
||||||
|
import androidx.camera.lifecycle.ProcessCameraProvider;
|
||||||
|
import androidx.camera.view.PreviewView;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import io.lbry.browser.MainActivity;
|
||||||
|
import io.lbry.browser.R;
|
||||||
|
import io.lbry.browser.adapter.GalleryGridAdapter;
|
||||||
|
import io.lbry.browser.listener.CameraPermissionListener;
|
||||||
|
import io.lbry.browser.listener.StoragePermissionListener;
|
||||||
|
import io.lbry.browser.model.GalleryItem;
|
||||||
|
import io.lbry.browser.tasks.localdata.LoadGalleryItemsTask;
|
||||||
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
|
import io.lbry.browser.utils.Helper;
|
||||||
|
import io.lbry.browser.utils.LbryAnalytics;
|
||||||
|
|
||||||
|
public class PublishFragment extends BaseFragment implements CameraPermissionListener, StoragePermissionListener {
|
||||||
|
|
||||||
|
private boolean loadGalleryItemsPending;
|
||||||
|
private PreviewView cameraPreview;
|
||||||
|
private RecyclerView galleryGrid;
|
||||||
|
private GalleryGridAdapter adapter;
|
||||||
|
private TextView noVideosLoaded;
|
||||||
|
private View loading;
|
||||||
|
|
||||||
|
private View buttonRecord;
|
||||||
|
private View buttonTakePhoto;
|
||||||
|
private View buttonUpload;
|
||||||
|
|
||||||
|
private boolean recordPending;
|
||||||
|
private boolean takePhotoPending;
|
||||||
|
private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
|
||||||
|
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
View root = inflater.inflate(R.layout.fragment_publish, container, false);
|
||||||
|
|
||||||
|
noVideosLoaded = root.findViewById(R.id.publish_grid_no_videos);
|
||||||
|
loading = root.findViewById(R.id.publish_grid_loading);
|
||||||
|
cameraPreview = root.findViewById(R.id.publish_camera_preview);
|
||||||
|
|
||||||
|
Context context = getContext();
|
||||||
|
galleryGrid = root.findViewById(R.id.publish_video_grid);
|
||||||
|
GridLayoutManager glm = new GridLayoutManager(context, 3);
|
||||||
|
galleryGrid.setLayoutManager(glm);
|
||||||
|
galleryGrid.addItemDecoration(new GalleryGridAdapter.GalleryGridItemDecoration(
|
||||||
|
3, Helper.getScaledValue(3, context.getResources().getDisplayMetrics().density)));
|
||||||
|
|
||||||
|
buttonRecord = root.findViewById(R.id.publish_record_button);
|
||||||
|
buttonTakePhoto = root.findViewById(R.id.publish_photo_button);
|
||||||
|
buttonUpload = root.findViewById(R.id.publish_upload_button);
|
||||||
|
|
||||||
|
buttonRecord.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
checkCameraPermissionAndRecord();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
buttonTakePhoto.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
checkCameraPermissionAndTakePhoto();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean cameraAvailable() {
|
||||||
|
Context context = getContext();
|
||||||
|
return context != null && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showCameraPreview() {
|
||||||
|
buttonRecord.setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
buttonTakePhoto.setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
displayPreviewWithCameraX();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayPreviewWithCameraX() {
|
||||||
|
Context context = getContext();
|
||||||
|
if (context != null) {
|
||||||
|
cameraProviderFuture = ProcessCameraProvider.getInstance(context);
|
||||||
|
cameraProviderFuture.addListener(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
|
||||||
|
if (cameraProvider != null) {
|
||||||
|
Preview preview = new Preview.Builder().build();
|
||||||
|
CameraSelector cameraSelector = new CameraSelector.Builder()
|
||||||
|
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner) context, cameraSelector, preview);
|
||||||
|
preview.setSurfaceProvider(cameraPreview.createSurfaceProvider(camera.getCameraInfo()));
|
||||||
|
} else {
|
||||||
|
android.util.Log.d("#HELP", "camera provider future is null?");
|
||||||
|
}
|
||||||
|
} catch (ExecutionException | InterruptedException ex) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, ContextCompat.getMainExecutor(context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCameraPermissionAndRecord() {
|
||||||
|
Context context = getContext();
|
||||||
|
if (!MainActivity.hasPermission(Manifest.permission.CAMERA, context)) {
|
||||||
|
recordPending = true;
|
||||||
|
MainActivity.requestPermission(
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
|
MainActivity.REQUEST_CAMERA_PERMISSION,
|
||||||
|
getString(R.string.camera_permission_rationale_record),
|
||||||
|
context,
|
||||||
|
true);
|
||||||
|
} else {
|
||||||
|
// start video record intent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCameraPermissionAndTakePhoto() {
|
||||||
|
Context context = getContext();
|
||||||
|
if (!MainActivity.hasPermission(Manifest.permission.CAMERA, context)) {
|
||||||
|
takePhotoPending = true;
|
||||||
|
MainActivity.requestPermission(
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
|
MainActivity.REQUEST_CAMERA_PERMISSION,
|
||||||
|
getString(R.string.camera_permission_rationale_photo),
|
||||||
|
context,
|
||||||
|
true);
|
||||||
|
} else {
|
||||||
|
// start video record intent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Publish", "Publish");
|
||||||
|
activity.addCameraPermissionListener(this);
|
||||||
|
activity.addStoragePermissionListener(this);
|
||||||
|
activity.hideFloatingWalletBalance();
|
||||||
|
|
||||||
|
|
||||||
|
if (cameraAvailable() && MainActivity.hasPermission(Manifest.permission.CAMERA, context)) {
|
||||||
|
showCameraPreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkStoragePermissionAndLoadVideos();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
public void onStop() {
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.removeCameraPermissionListener(this);
|
||||||
|
activity.removeStoragePermissionListener(this);
|
||||||
|
activity.showFloatingWalletBalance();
|
||||||
|
}
|
||||||
|
CameraX.unbindAll();
|
||||||
|
super.onStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkStoragePermissionAndLoadVideos() {
|
||||||
|
Context context = getContext();
|
||||||
|
if (MainActivity.hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, context)) {
|
||||||
|
loadGalleryItems();
|
||||||
|
} else {
|
||||||
|
loadGalleryItemsPending = true;
|
||||||
|
MainActivity.requestPermission(
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
|
MainActivity.REQUEST_STORAGE_PERMISSION,
|
||||||
|
getString(R.string.storage_permission_rationale_download),
|
||||||
|
context,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadGalleryItems() {
|
||||||
|
Context context = getContext();
|
||||||
|
Helper.setViewVisibility(noVideosLoaded, View.GONE);
|
||||||
|
LoadGalleryItemsTask task = new LoadGalleryItemsTask(loading, context, new LoadGalleryItemsTask.LoadGalleryHandler() {
|
||||||
|
@Override
|
||||||
|
public void onItemLoaded(GalleryItem item) {
|
||||||
|
if (context != null) {
|
||||||
|
if (adapter == null) {
|
||||||
|
adapter = new GalleryGridAdapter(Arrays.asList(item), context);
|
||||||
|
} else {
|
||||||
|
adapter.addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (galleryGrid.getAdapter() == null) {
|
||||||
|
galleryGrid.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
Helper.setViewVisibility(loading, adapter == null || adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAllItemsLoaded(List<GalleryItem> items) {
|
||||||
|
if (context != null) {
|
||||||
|
if (adapter == null) {
|
||||||
|
adapter = new GalleryGridAdapter(items, context);
|
||||||
|
} else {
|
||||||
|
adapter.addItems(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (galleryGrid.getAdapter() == null) {
|
||||||
|
galleryGrid.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkNoVideosLoaded();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkNoVideosLoaded() {
|
||||||
|
Helper.setViewVisibility(noVideosLoaded, adapter == null || adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCameraPermissionGranted() {
|
||||||
|
if (recordPending) {
|
||||||
|
// record video
|
||||||
|
recordPending = false;
|
||||||
|
} else if (takePhotoPending) {
|
||||||
|
// take a photo
|
||||||
|
takePhotoPending = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCameraPermissionRefused() {
|
||||||
|
if (takePhotoPending) {
|
||||||
|
takePhotoPending = false;
|
||||||
|
Snackbar.make(getView(), R.string.camera_permission_rationale_photo, Toast.LENGTH_LONG).
|
||||||
|
setBackgroundTint(Color.RED).setTextColor(Color.WHITE).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
recordPending = false;
|
||||||
|
Snackbar.make(getView(), R.string.camera_permission_rationale_record, Toast.LENGTH_LONG).
|
||||||
|
setBackgroundTint(Color.RED).setTextColor(Color.WHITE).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRecordAudioPermissionGranted() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRecordAudioPermissionRefused() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStoragePermissionGranted() {
|
||||||
|
if (loadGalleryItemsPending) {
|
||||||
|
loadGalleryItemsPending = false;
|
||||||
|
loadGalleryItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStoragePermissionRefused() {
|
||||||
|
Snackbar.make(getView(), R.string.storage_permission_rationale_videos, Snackbar.LENGTH_LONG).setBackgroundTint(
|
||||||
|
ContextCompat.getColor(getContext(), R.color.red)
|
||||||
|
).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldHideGlobalPlayer() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldSuspendGlobalPlayer() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,321 @@
|
||||||
|
package io.lbry.browser.ui.publish;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.appcompat.view.ActionMode;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import io.lbry.browser.MainActivity;
|
||||||
|
import io.lbry.browser.R;
|
||||||
|
import io.lbry.browser.adapter.ClaimListAdapter;
|
||||||
|
import io.lbry.browser.listener.SdkStatusListener;
|
||||||
|
import io.lbry.browser.listener.SelectionModeListener;
|
||||||
|
import io.lbry.browser.model.Claim;
|
||||||
|
import io.lbry.browser.tasks.claim.AbandonChannelTask;
|
||||||
|
import io.lbry.browser.tasks.claim.AbandonHandler;
|
||||||
|
import io.lbry.browser.tasks.claim.ClaimListResultHandler;
|
||||||
|
import io.lbry.browser.tasks.claim.ClaimListTask;
|
||||||
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
|
import io.lbry.browser.utils.Helper;
|
||||||
|
import io.lbry.browser.utils.Lbry;
|
||||||
|
import io.lbry.browser.utils.LbryAnalytics;
|
||||||
|
|
||||||
|
public class PublishesFragment extends BaseFragment implements ActionMode.Callback, SelectionModeListener, SdkStatusListener {
|
||||||
|
|
||||||
|
private Button buttonNewPublish;
|
||||||
|
private FloatingActionButton fabNewPublish;
|
||||||
|
private ActionMode actionMode;
|
||||||
|
private View emptyView;
|
||||||
|
private View layoutSdkInitializing;
|
||||||
|
private ProgressBar loading;
|
||||||
|
private ProgressBar bigLoading;
|
||||||
|
private RecyclerView contentList;
|
||||||
|
private ClaimListAdapter adapter;
|
||||||
|
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
View root = inflater.inflate(R.layout.fragment_publishes, container, false);
|
||||||
|
|
||||||
|
buttonNewPublish = root.findViewById(R.id.publishes_create_button);
|
||||||
|
fabNewPublish = root.findViewById(R.id.publishes_fab_new_publish);
|
||||||
|
buttonNewPublish.setOnClickListener(newPublishClickListener);
|
||||||
|
fabNewPublish.setOnClickListener(newPublishClickListener);
|
||||||
|
|
||||||
|
emptyView = root.findViewById(R.id.publishes_empty_container);
|
||||||
|
layoutSdkInitializing = root.findViewById(R.id.container_sdk_initializing);
|
||||||
|
contentList = root.findViewById(R.id.publishes_list);
|
||||||
|
LinearLayoutManager llm = new LinearLayoutManager(getContext());
|
||||||
|
contentList.setLayoutManager(llm);
|
||||||
|
loading = root.findViewById(R.id.publishes_list_loading);
|
||||||
|
bigLoading = root.findViewById(R.id.publishes_list_big_loading);
|
||||||
|
|
||||||
|
layoutSdkInitializing.setVisibility(Lbry.SDK_READY ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
private View.OnClickListener newPublishClickListener = new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
//((MainActivity) context).openPublishForm(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
Context context = getContext();
|
||||||
|
if (context != null) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.hideFloatingWalletBalance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.showFloatingWalletBalance();
|
||||||
|
}
|
||||||
|
super.onStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.setWunderbarValue(null);
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Publishes", "Publishes");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Lbry.SDK_READY) {
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.addSdkStatusListener(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onSdkReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSdkReady() {
|
||||||
|
Helper.setViewVisibility(layoutSdkInitializing, View.GONE);
|
||||||
|
Helper.setViewVisibility(fabNewPublish, View.VISIBLE);
|
||||||
|
if (adapter != null && contentList != null) {
|
||||||
|
contentList.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
fetchPublishes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public View getLoading() {
|
||||||
|
return (adapter == null || adapter.getItemCount() == 0) ? bigLoading : loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkNoPublishes() {
|
||||||
|
Helper.setViewVisibility(emptyView, adapter == null || adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fetchPublishes() {
|
||||||
|
Helper.setViewVisibility(emptyView, View.GONE);
|
||||||
|
ClaimListTask task = new ClaimListTask(Arrays.asList(Claim.TYPE_STREAM, Claim.TYPE_REPOST), getLoading(), new ClaimListResultHandler() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<Claim> claims) {
|
||||||
|
Lbry.ownClaims = Helper.filterDeletedClaims(new ArrayList<>(claims));
|
||||||
|
Context context = getContext();
|
||||||
|
if (adapter == null) {
|
||||||
|
adapter = new ClaimListAdapter(claims, context);
|
||||||
|
adapter.setCanEnterSelectionMode(true);
|
||||||
|
adapter.setSelectionModeListener(PublishesFragment.this);
|
||||||
|
adapter.setListener(new ClaimListAdapter.ClaimListItemListener() {
|
||||||
|
@Override
|
||||||
|
public void onClaimClicked(Claim claim) {
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
((MainActivity) context).openFileClaim(claim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (contentList != null) {
|
||||||
|
contentList.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
adapter.setItems(claims);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkNoPublishes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception error) {
|
||||||
|
checkNoPublishes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onEnterSelectionMode() {
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.startSupportActionMode(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void onItemSelectionToggled() {
|
||||||
|
if (actionMode != null) {
|
||||||
|
actionMode.setTitle(String.valueOf(adapter.getSelectedCount()));
|
||||||
|
actionMode.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void onExitSelectionMode() {
|
||||||
|
if (actionMode != null) {
|
||||||
|
actionMode.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
|
||||||
|
this.actionMode = actionMode;
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
if (!activity.isDarkMode()) {
|
||||||
|
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actionMode.getMenuInflater().inflate(R.menu.menu_claim_list, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onDestroyActionMode(ActionMode actionMode) {
|
||||||
|
if (adapter != null) {
|
||||||
|
adapter.clearSelectedItems();
|
||||||
|
adapter.setInSelectionMode(false);
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
Context context = getContext();
|
||||||
|
if (context != null) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
if (!activity.isDarkMode()) {
|
||||||
|
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.actionMode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepareActionMode(androidx.appcompat.view.ActionMode actionMode, Menu menu) {
|
||||||
|
int selectionCount = adapter != null ? adapter.getSelectedCount() : 0;
|
||||||
|
menu.findItem(R.id.action_edit).setVisible(selectionCount == 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onActionItemClicked(androidx.appcompat.view.ActionMode actionMode, MenuItem menuItem) {
|
||||||
|
if (R.id.action_edit == menuItem.getItemId()) {
|
||||||
|
if (adapter != null && adapter.getSelectedCount() > 0) {
|
||||||
|
Claim claim = adapter.getSelectedItems().get(0);
|
||||||
|
// start channel editor with the claim
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("claim", claim);
|
||||||
|
/*((MainActivity) context).openFragment(PublishFormFragment.class, true, NavMenuItem.ID_ITEM_NEW_PUBLISH, params);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
actionMode.finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (R.id.action_delete == menuItem.getItemId()) {
|
||||||
|
if (adapter != null && adapter.getSelectedCount() > 0) {
|
||||||
|
final List<Claim> selectedClaims = new ArrayList<>(adapter.getSelectedItems());
|
||||||
|
String message = getResources().getQuantityString(R.plurals.confirm_delete_publishes, selectedClaims.size());
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()).
|
||||||
|
setTitle(R.string.delete_selection).
|
||||||
|
setMessage(message)
|
||||||
|
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
handleDeleteSelectedClaims(selectedClaims);
|
||||||
|
}
|
||||||
|
}).setNegativeButton(R.string.no, null);
|
||||||
|
builder.show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleDeleteSelectedClaims(List<Claim> selectedClaims) {
|
||||||
|
List<String> claimIds = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Claim claim : selectedClaims) {
|
||||||
|
claimIds.add(claim.getClaimId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actionMode != null) {
|
||||||
|
actionMode.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
Helper.setViewVisibility(contentList, View.INVISIBLE);
|
||||||
|
Helper.setViewVisibility(fabNewPublish, View.INVISIBLE);
|
||||||
|
AbandonChannelTask task = new AbandonChannelTask(claimIds, bigLoading, new AbandonHandler() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(List<String> successfulClaimIds, List<String> failedClaimIds, List<Exception> errors) {
|
||||||
|
View root = getView();
|
||||||
|
if (root != null) {
|
||||||
|
if (failedClaimIds.size() > 0) {
|
||||||
|
Snackbar.make(root, R.string.one_or_more_publishes_failed_abandon, Snackbar.LENGTH_LONG).
|
||||||
|
setBackgroundTint(Color.RED).setTextColor(Color.WHITE).show();
|
||||||
|
} else if (successfulClaimIds.size() == claimIds.size()) {
|
||||||
|
try {
|
||||||
|
String message = getResources().getQuantityString(R.plurals.publishes_deleted, successfulClaimIds.size());
|
||||||
|
Snackbar.make(root, message, Snackbar.LENGTH_LONG).show();
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Lbry.abandonedClaimIds.addAll(successfulClaimIds);
|
||||||
|
if (adapter != null) {
|
||||||
|
adapter.setItems(Helper.filterDeletedClaims(adapter.getItems()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Helper.setViewVisibility(contentList, View.VISIBLE);
|
||||||
|
Helper.setViewVisibility(fabNewPublish, View.VISIBLE);
|
||||||
|
checkNoPublishes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
}
|
|
@ -214,8 +214,13 @@ public class SearchFragment extends BaseFragment implements
|
||||||
}
|
}
|
||||||
|
|
||||||
searchLoading = true;
|
searchLoading = true;
|
||||||
|
Context context = getContext();
|
||||||
|
boolean canShowMatureContent = false;
|
||||||
|
if (context != null) {
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||||
boolean canShowMatureContent = sp.getBoolean(MainActivity.PREFERENCE_KEY_SHOW_MATURE_CONTENT, false);
|
canShowMatureContent = sp.getBoolean(MainActivity.PREFERENCE_KEY_SHOW_MATURE_CONTENT, false);
|
||||||
|
}
|
||||||
|
|
||||||
LighthouseSearchTask task = new LighthouseSearchTask(
|
LighthouseSearchTask task = new LighthouseSearchTask(
|
||||||
currentQuery, PAGE_SIZE, currentFrom, canShowMatureContent, null, loadingView, new ClaimSearchTask.ClaimSearchResultHandler() {
|
currentQuery, PAGE_SIZE, currentFrom, canShowMatureContent, null, loadingView, new ClaimSearchTask.ClaimSearchResultHandler() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -233,7 +233,7 @@ public class RewardsFragment extends BaseFragment implements RewardListAdapter.R
|
||||||
Helper.shortCurrencyFormat(Lbryio.totalUnclaimedRewardAmount));
|
Helper.shortCurrencyFormat(Lbryio.totalUnclaimedRewardAmount));
|
||||||
double unclaimedRewardAmountUsd = Lbryio.totalUnclaimedRewardAmount * Lbryio.LBCUSDRate;
|
double unclaimedRewardAmountUsd = Lbryio.totalUnclaimedRewardAmount * Lbryio.LBCUSDRate;
|
||||||
Helper.setViewText(textAccountDriverTitle, accountDriverTitle);
|
Helper.setViewText(textAccountDriverTitle, accountDriverTitle);
|
||||||
Helper.setViewText(textFreeCreditsWorth, getString(R.string.free_credits_worth, Helper.USD_CURRENCY_FORMAT.format(unclaimedRewardAmountUsd)));
|
Helper.setViewText(textFreeCreditsWorth, getString(R.string.free_credits_worth, Helper.SIMPLE_CURRENCY_FORMAT.format(unclaimedRewardAmountUsd)));
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
// pass
|
// pass
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,8 +398,12 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkReceiveAddress() {
|
private void checkReceiveAddress() {
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
|
Context context = getContext();
|
||||||
String receiveAddress = sp.getString(MainActivity.PREFERENCE_KEY_INTERNAL_WALLET_RECEIVE_ADDRESS, null);
|
String receiveAddress = null;
|
||||||
|
if (context != null) {
|
||||||
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
receiveAddress = sp.getString(MainActivity.PREFERENCE_KEY_INTERNAL_WALLET_RECEIVE_ADDRESS, null);
|
||||||
|
}
|
||||||
if (Helper.isNullOrEmpty(receiveAddress)) {
|
if (Helper.isNullOrEmpty(receiveAddress)) {
|
||||||
if (Lbry.SDK_READY) {
|
if (Lbry.SDK_READY) {
|
||||||
generateNewAddress();
|
generateNewAddress();
|
||||||
|
@ -505,15 +509,16 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
|
||||||
double tipsBalance = walletBalance.getTips().doubleValue();
|
double tipsBalance = walletBalance.getTips().doubleValue();
|
||||||
double tipsUsdBalance = tipsBalance * Lbryio.LBCUSDRate;
|
double tipsUsdBalance = tipsBalance * Lbryio.LBCUSDRate;
|
||||||
|
|
||||||
Helper.setViewText(textWalletBalance, Helper.LBC_CURRENCY_FORMAT.format(balance));
|
String formattedBalance = Helper.SIMPLE_CURRENCY_FORMAT.format(balance);
|
||||||
|
Helper.setViewText(textWalletBalance, balance > 0 && formattedBalance.equals("0") ? Helper.FULL_LBC_CURRENCY_FORMAT.format(balance) : formattedBalance);
|
||||||
Helper.setViewText(textTipsBalance, Helper.shortCurrencyFormat(tipsBalance));
|
Helper.setViewText(textTipsBalance, Helper.shortCurrencyFormat(tipsBalance));
|
||||||
Helper.setViewText(textClaimsBalance, Helper.shortCurrencyFormat(walletBalance.getClaims().doubleValue()));
|
Helper.setViewText(textClaimsBalance, Helper.shortCurrencyFormat(walletBalance.getClaims().doubleValue()));
|
||||||
Helper.setViewText(textSupportsBalance, Helper.shortCurrencyFormat(walletBalance.getSupports().doubleValue()));
|
Helper.setViewText(textSupportsBalance, Helper.shortCurrencyFormat(walletBalance.getSupports().doubleValue()));
|
||||||
Helper.setViewText(textWalletInlineBalance, Helper.shortCurrencyFormat(balance));
|
Helper.setViewText(textWalletInlineBalance, Helper.shortCurrencyFormat(balance));
|
||||||
if (Lbryio.LBCUSDRate > 0) {
|
if (Lbryio.LBCUSDRate > 0) {
|
||||||
// only update display usd values if the rate is loaded
|
// only update display usd values if the rate is loaded
|
||||||
Helper.setViewText(textWalletBalanceUSD, String.format("≈$%s", Helper.USD_CURRENCY_FORMAT.format(usdBalance)));
|
Helper.setViewText(textWalletBalanceUSD, String.format("≈$%s", Helper.SIMPLE_CURRENCY_FORMAT.format(usdBalance)));
|
||||||
Helper.setViewText(textTipsBalanceUSD, String.format("≈$%s", Helper.USD_CURRENCY_FORMAT.format(tipsUsdBalance)));
|
Helper.setViewText(textTipsBalanceUSD, String.format("≈$%s", Helper.SIMPLE_CURRENCY_FORMAT.format(tipsUsdBalance)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,8 @@ public final class Helper {
|
||||||
public static final String LBC_CURRENCY_FORMAT_PATTERN = "#,###.##";
|
public static final String LBC_CURRENCY_FORMAT_PATTERN = "#,###.##";
|
||||||
public static final String FILE_SIZE_FORMAT_PATTERN = "#,###.#";
|
public static final String FILE_SIZE_FORMAT_PATTERN = "#,###.#";
|
||||||
public static final DecimalFormat LBC_CURRENCY_FORMAT = new DecimalFormat(LBC_CURRENCY_FORMAT_PATTERN);
|
public static final DecimalFormat LBC_CURRENCY_FORMAT = new DecimalFormat(LBC_CURRENCY_FORMAT_PATTERN);
|
||||||
public static final DecimalFormat USD_CURRENCY_FORMAT = new DecimalFormat("#,##0.00");
|
public static final DecimalFormat FULL_LBC_CURRENCY_FORMAT = new DecimalFormat("#,###.########");
|
||||||
|
public static final DecimalFormat SIMPLE_CURRENCY_FORMAT = new DecimalFormat("#,##0.00");
|
||||||
public static final String EXPLORER_TX_PREFIX = "https://explorer.lbry.com/tx";
|
public static final String EXPLORER_TX_PREFIX = "https://explorer.lbry.com/tx";
|
||||||
|
|
||||||
public static boolean isNull(String value) {
|
public static boolean isNull(String value) {
|
||||||
|
@ -300,7 +301,7 @@ public final class Helper {
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
return format.format(value);
|
return format.format(value).equals("0") ? FULL_LBC_CURRENCY_FORMAT.format(value) : format.format(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getValue(CharSequence cs) {
|
public static String getValue(CharSequence cs) {
|
||||||
|
@ -680,4 +681,8 @@ public final class Helper {
|
||||||
}
|
}
|
||||||
return channelName;
|
return channelName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getScaledValue(int value, float scale) {
|
||||||
|
return (int) (value * scale + 0.5f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ import okhttp3.Response;
|
||||||
public final class Lbryio {
|
public final class Lbryio {
|
||||||
|
|
||||||
// TODO: Get this from the bundled aar
|
// TODO: Get this from the bundled aar
|
||||||
public static String SDK_VERSION = "0.73.1";
|
public static String SDK_VERSION = "0.74.0";
|
||||||
|
|
||||||
public static User currentUser;
|
public static User currentUser;
|
||||||
public static boolean userHasSyncedWallet = false;
|
public static boolean userHasSyncedWallet = false;
|
||||||
|
@ -121,7 +121,7 @@ public final class Lbryio {
|
||||||
|
|
||||||
if (options != null) {
|
if (options != null) {
|
||||||
for (Map.Entry<String, String> option : options.entrySet()) {
|
for (Map.Entry<String, String> option : options.entrySet()) {
|
||||||
qs.append(delim).append(option.getKey()).append("=").append(URLEncoder.encode(option.getValue(), "UTF8"));
|
qs.append(delim).append(option.getKey()).append("=").append(URLEncoder.encode(Helper.isNull(option.getValue()) ? "" : option.getValue(), "UTF8"));
|
||||||
delim = "&";
|
delim = "&";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
14
app/src/main/res/drawable-anydpi/ic_photo.xml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:alpha="0.8">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
|
||||||
|
</vector>
|
11
app/src/main/res/drawable-anydpi/ic_record.xml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:alpha="0.8">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z"/>
|
||||||
|
</vector>
|
11
app/src/main/res/drawable-anydpi/ic_upload.xml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:alpha="0.8">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M9,16h6v-6h4l-7,-7 -7,7h4zM5,18h14v2L5,20z"/>
|
||||||
|
</vector>
|
BIN
app/src/main/res/drawable-hdpi/ic_photo.png
Normal file
After Width: | Height: | Size: 350 B |
BIN
app/src/main/res/drawable-hdpi/ic_record.png
Normal file
After Width: | Height: | Size: 188 B |
BIN
app/src/main/res/drawable-hdpi/ic_upload.png
Normal file
After Width: | Height: | Size: 171 B |
BIN
app/src/main/res/drawable-mdpi/ic_photo.png
Normal file
After Width: | Height: | Size: 228 B |
BIN
app/src/main/res/drawable-mdpi/ic_record.png
Normal file
After Width: | Height: | Size: 140 B |
BIN
app/src/main/res/drawable-mdpi/ic_upload.png
Normal file
After Width: | Height: | Size: 131 B |
BIN
app/src/main/res/drawable-xhdpi/ic_photo.png
Normal file
After Width: | Height: | Size: 435 B |
BIN
app/src/main/res/drawable-xhdpi/ic_record.png
Normal file
After Width: | Height: | Size: 195 B |
BIN
app/src/main/res/drawable-xhdpi/ic_upload.png
Normal file
After Width: | Height: | Size: 182 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_photo.png
Normal file
After Width: | Height: | Size: 662 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_record.png
Normal file
After Width: | Height: | Size: 247 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_upload.png
Normal file
After Width: | Height: | Size: 237 B |
|
@ -40,6 +40,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/uri_placeholder"
|
android:hint="@string/uri_placeholder"
|
||||||
android:imeOptions="actionGo"
|
android:imeOptions="actionGo"
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
android:selectAllOnFocus="true"
|
android:selectAllOnFocus="true"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textFontWeight="300"
|
android:textFontWeight="300"
|
||||||
|
|
179
app/src/main/res/layout/fragment_publish.xml
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/publishBackground">
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/publish_main_actions"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="300dp">
|
||||||
|
<androidx.camera.view.PreviewView
|
||||||
|
android:id="@+id/publish_camera_preview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:weightSum="2">
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/publish_record_button"
|
||||||
|
android:background="@android:color/black"
|
||||||
|
android:clickable="true"
|
||||||
|
android:foreground="?attr/selectableItemBackground"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginLeft="-1.5dp">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:tint="@color/white"
|
||||||
|
android:src="@drawable/ic_record" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/record"
|
||||||
|
android:textAllCaps="true"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<View
|
||||||
|
android:id="@+id/publish_vertical_divider"
|
||||||
|
android:background="@color/publishBackground"
|
||||||
|
android:layout_width="3dp"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/publish_photo_button"
|
||||||
|
android:clickable="true"
|
||||||
|
android:background="@android:color/black"
|
||||||
|
android:foreground="?attr/selectableItemBackground"
|
||||||
|
android:layout_toRightOf="@id/publish_vertical_divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="148.5dp">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:tint="@color/white"
|
||||||
|
android:src="@drawable/ic_photo" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/take_photo"
|
||||||
|
android:textAllCaps="true"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/publish_photo_upload_divider"
|
||||||
|
android:background="@color/publishBackground"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="3dp"
|
||||||
|
android:layout_below="@id/publish_photo_button" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/publish_upload_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="148.5dp"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_toRightOf="@id/publish_vertical_divider"
|
||||||
|
android:clickable="true"
|
||||||
|
android:background="@android:color/black"
|
||||||
|
android:foreground="?attr/selectableItemBackground"
|
||||||
|
>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:tint="@color/white"
|
||||||
|
android:src="@drawable/ic_upload" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/upload_file"
|
||||||
|
android:textAllCaps="true"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/publish_video_grid"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_below="@id/publish_main_actions"
|
||||||
|
android:layout_marginTop="3dp" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/publish_grid_no_videos"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/publish_main_actions"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/no_videos_found"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/publish_grid_loading"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_below="@id/publish_main_actions"
|
||||||
|
android:visibility="gone">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ProgressBar
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/loading_videos"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
</RelativeLayout>
|
75
app/src/main/res/layout/fragment_publishes.xml
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:focusedByDefault="true">
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/publishes_list_big_loading"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:visibility="gone" />
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/publishes_list_loading"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/publishes_list"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/publishes_empty_container"
|
||||||
|
android:background="@color/pageBackground"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone">
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:padding="36dp">
|
||||||
|
<ImageView
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_width="160dp"
|
||||||
|
android:layout_height="300dp"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:src="@drawable/gerbil_happy" />
|
||||||
|
<TextView
|
||||||
|
android:text="@string/no_channel_created"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textFontWeight="300"/>
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/publishes_create_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/new_publish" />
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
<include layout="@layout/container_sdk_initializing" />
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/publishes_fab_new_publish"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:src="@drawable/ic_add"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</RelativeLayout>
|
28
app/src/main/res/layout/list_item_gallery.xml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:foreground="?attr/selectableItemBackground">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/gallery_item_thumbnail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
<TextView
|
||||||
|
android:background="@android:color/black"
|
||||||
|
android:id="@+id/gallery_item_duration"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_marginRight="4dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="10sp"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:padding="2dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</RelativeLayout>
|
|
@ -15,6 +15,7 @@
|
||||||
<color name="smallIconBackground">#55000000</color>
|
<color name="smallIconBackground">#55000000</color>
|
||||||
<color name="costBackground">#F4E866</color>
|
<color name="costBackground">#F4E866</color>
|
||||||
|
|
||||||
|
<color name="publishBackground">#333333</color>
|
||||||
<color name="playerControlsBackground">#33000000</color>
|
<color name="playerControlsBackground">#33000000</color>
|
||||||
<color name="scrubberColor">@color/nextLbryGreen</color>
|
<color name="scrubberColor">@color/nextLbryGreen</color>
|
||||||
<color name="playedColor">@color/nextLbryGreen</color>
|
<color name="playedColor">@color/nextLbryGreen</color>
|
||||||
|
|
|
@ -93,6 +93,27 @@
|
||||||
<item quantity="other">%1$s followers</item>
|
<item quantity="other">%1$s followers</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
|
<!-- Publish -->
|
||||||
|
<string name="record">Record</string>
|
||||||
|
<string name="take_photo">Take a Photo</string>
|
||||||
|
<string name="upload_file">Upload a file</string>
|
||||||
|
<string name="no_videos_found">We could not find any videos on your device. Take a photo or record a video to get started.</string>
|
||||||
|
<string name="loading_videos">Please wait while we load your videos...</string>
|
||||||
|
<string name="storage_permission_rationale_videos">LBRY requires access to be able to display and publish your videos, images and other files from your device.</string>
|
||||||
|
<string name="camera_permission_rationale_record">LBRY requires access to your camera to record videos.</string>
|
||||||
|
<string name="camera_permission_rationale_photo">LBRY requires access to your camera to take photos.</string>
|
||||||
|
|
||||||
|
<!-- Publishes -->
|
||||||
|
<string name="one_or_more_publishes_failed_abandon">One or more content items could not be deleted at this time. Please try again later.</string>
|
||||||
|
<plurals name="confirm_delete_publishes">
|
||||||
|
<item quantity="one">Are you sure you want to delete the selected content item?</item>
|
||||||
|
<item quantity="other">Are you sure you want to delete the selected content items?</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="publishes_deleted">
|
||||||
|
<item quantity="one">The content item was successfully deleted.</item>
|
||||||
|
<item quantity="other">The content items were successfully deleted.</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
<!-- Splash -->
|
<!-- Splash -->
|
||||||
<string name="oops_something_went_wrong">Oops! Something went wrong.</string>
|
<string name="oops_something_went_wrong">Oops! Something went wrong.</string>
|
||||||
<string name="installation_id_loaded">Loaded Installation ID.</string>
|
<string name="installation_id_loaded">Loaded Installation ID.</string>
|
||||||
|
@ -323,7 +344,7 @@
|
||||||
<string name="item_pending_blockchain">The claim is pending publish on the blockchain. You will be able to access or edit the claim in a few moments.</string>
|
<string name="item_pending_blockchain">The claim is pending publish on the blockchain. You will be able to access or edit the claim in a few moments.</string>
|
||||||
<string name="pending">Pending</string>
|
<string name="pending">Pending</string>
|
||||||
<string name="create">Create</string>
|
<string name="create">Create</string>
|
||||||
<string name="one_or_more_channels_failed_abandon">One or moe channels could not be deleted at this time. Please try again later.</string>
|
<string name="one_or_more_channels_failed_abandon">One or more channels could not be deleted at this time. Please try again later.</string>
|
||||||
<plurals name="min_deposit_required">
|
<plurals name="min_deposit_required">
|
||||||
<item quantity="one">A minimum deposit of %1$s credit is required.</item>
|
<item quantity="one">A minimum deposit of %1$s credit is required.</item>
|
||||||
<item quantity="other">A minimum deposit of %1$s credits is required.</item>
|
<item quantity="other">A minimum deposit of %1$s credits is required.</item>
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
>
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/user_interface"
|
android:title="@string/user_interface"
|
||||||
app:iconSpaceReserved="false">
|
app:iconSpaceReserved="false">
|
||||||
|
|