sdk 0.72.0. Customize player view and controls.
|
@ -86,8 +86,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.71.0-release__arm.aar')
|
__32bitImplementation files('libs/lbrysdk-0.72.0-release__arm.aar')
|
||||||
__64bitImplementation files('libs/lbrysdk-0.71.0-release__arm64.aar')
|
__64bitImplementation files('libs/lbrysdk-0.72.0-release__arm64.aar')
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
|
|
@ -19,6 +19,19 @@
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true">
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||||
|
android:resource="@drawable/ic_lbry" />
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.firebase.messaging.default_notification_color"
|
||||||
|
android:resource="@color/lbryGreen" />
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
||||||
|
android:value="@string/default_notification_channel_id"/>
|
||||||
|
|
||||||
|
<meta-data android:name="wakelock" android:value="0"/>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|screenLayout"
|
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|screenLayout"
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
|
@ -58,6 +71,14 @@
|
||||||
android:parentActivityName=".MainActivity"
|
android:parentActivityName=".MainActivity"
|
||||||
android:supportsPictureInPicture="true"
|
android:supportsPictureInPicture="true"
|
||||||
android:theme="@style/AppTheme.NoActionBarBlack" />
|
android:theme="@style/AppTheme.NoActionBarBlack" />
|
||||||
</application>
|
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name="io.lbry.browser.LbrynetMessagingService"
|
||||||
|
android:exported="false">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
</application>
|
||||||
</manifest>
|
</manifest>
|
|
@ -1,29 +1,39 @@
|
||||||
package io.lbry.browser;
|
package io.lbry.browser;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.app.PictureInPictureParams;
|
import android.app.PictureInPictureParams;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.service.voice.VoiceInteractionSession;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
|
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||||
import androidx.core.widget.NestedScrollView;
|
import androidx.core.widget.NestedScrollView;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||||
|
@ -34,12 +44,17 @@ import com.google.android.exoplayer2.ui.PlayerView;
|
||||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.android.flexbox.FlexboxLayoutManager;
|
import com.google.android.flexbox.FlexboxLayoutManager;
|
||||||
|
import com.google.android.material.button.MaterialButton;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import io.lbry.browser.adapter.ClaimListAdapter;
|
import io.lbry.browser.adapter.ClaimListAdapter;
|
||||||
import io.lbry.browser.adapter.TagListAdapter;
|
import io.lbry.browser.adapter.TagListAdapter;
|
||||||
|
@ -47,15 +62,22 @@ import io.lbry.browser.dialog.SendTipDialogFragment;
|
||||||
import io.lbry.browser.exceptions.LbryUriException;
|
import io.lbry.browser.exceptions.LbryUriException;
|
||||||
import io.lbry.browser.model.Claim;
|
import io.lbry.browser.model.Claim;
|
||||||
import io.lbry.browser.model.ClaimCacheKey;
|
import io.lbry.browser.model.ClaimCacheKey;
|
||||||
|
import io.lbry.browser.model.Fee;
|
||||||
import io.lbry.browser.model.File;
|
import io.lbry.browser.model.File;
|
||||||
import io.lbry.browser.model.Tag;
|
import io.lbry.browser.model.Tag;
|
||||||
|
import io.lbry.browser.model.lbryinc.Reward;
|
||||||
import io.lbry.browser.tasks.ClaimListResultHandler;
|
import io.lbry.browser.tasks.ClaimListResultHandler;
|
||||||
import io.lbry.browser.tasks.ClaimSearchTask;
|
import io.lbry.browser.tasks.ClaimSearchTask;
|
||||||
import io.lbry.browser.tasks.FileListTask;
|
import io.lbry.browser.tasks.FileListTask;
|
||||||
|
import io.lbry.browser.tasks.GenericTaskHandler;
|
||||||
import io.lbry.browser.tasks.LighthouseSearchTask;
|
import io.lbry.browser.tasks.LighthouseSearchTask;
|
||||||
import io.lbry.browser.tasks.ResolveTask;
|
import io.lbry.browser.tasks.ResolveTask;
|
||||||
|
import io.lbry.browser.tasks.lbryinc.ClaimRewardTask;
|
||||||
|
import io.lbry.browser.tasks.lbryinc.FetchStatCountTask;
|
||||||
|
import io.lbry.browser.tasks.lbryinc.LogFileViewTask;
|
||||||
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.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
|
|
||||||
public class FileViewActivity extends AppCompatActivity {
|
public class FileViewActivity extends AppCompatActivity {
|
||||||
|
@ -65,16 +87,23 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
private static final int SHARE_REQUEST_CODE = 3001;
|
private static final int SHARE_REQUEST_CODE = 3001;
|
||||||
private static boolean startingShareActivity;
|
private static boolean startingShareActivity;
|
||||||
|
|
||||||
private SimpleExoPlayer player;
|
|
||||||
private boolean hasLoadedFirstBalance;
|
private boolean hasLoadedFirstBalance;
|
||||||
private boolean loadFilePending;
|
private boolean loadFilePending;
|
||||||
private boolean resolving;
|
private boolean resolving;
|
||||||
private Claim claim;
|
private Claim claim;
|
||||||
|
private String currentUrl;
|
||||||
private ClaimListAdapter relatedContentAdapter;
|
private ClaimListAdapter relatedContentAdapter;
|
||||||
private File file;
|
private File file;
|
||||||
private BroadcastReceiver sdkReceiver;
|
private BroadcastReceiver sdkReceiver;
|
||||||
private Player.EventListener fileViewPlayerListener;
|
private Player.EventListener fileViewPlayerListener;
|
||||||
|
|
||||||
|
private long elapsedDuration = 0;
|
||||||
|
private long totalDuration = 0;
|
||||||
|
private boolean elapsedPlaybackScheduled;
|
||||||
|
private ScheduledExecutorService elapsedPlaybackScheduler;
|
||||||
|
private boolean playbackStarted;
|
||||||
|
private long startTimeMillis;
|
||||||
|
|
||||||
private View buttonShareAction;
|
private View buttonShareAction;
|
||||||
private View buttonTipAction;
|
private View buttonTipAction;
|
||||||
private View buttonRepostAction;
|
private View buttonRepostAction;
|
||||||
|
@ -118,6 +147,8 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
setContentView(R.layout.activity_file_view);
|
setContentView(R.layout.activity_file_view);
|
||||||
|
|
||||||
|
currentUrl = url;
|
||||||
|
logUrlEvent(url);
|
||||||
if (claim == null) {
|
if (claim == null) {
|
||||||
resolveUrl(url);
|
resolveUrl(url);
|
||||||
}
|
}
|
||||||
|
@ -127,9 +158,23 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
fileViewPlayerListener = new Player.EventListener() {
|
fileViewPlayerListener = new Player.EventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||||
/*if (playbackState == Player.STATE_READY) {
|
if (playbackState == Player.STATE_READY) {
|
||||||
MainActivity.setNowPlayingClaim(claim, FileViewActivity.this);
|
if (totalDuration == 0) {
|
||||||
}*/
|
elapsedDuration = MainActivity.appPlayer.getCurrentPosition();
|
||||||
|
totalDuration = MainActivity.appPlayer.getDuration();
|
||||||
|
}
|
||||||
|
if (!playbackStarted) {
|
||||||
|
logPlay(currentUrl, startTimeMillis);
|
||||||
|
playbackStarted = true;
|
||||||
|
}
|
||||||
|
renderTotalDuration();
|
||||||
|
scheduleElapsedPlayback();
|
||||||
|
hideBuffering();
|
||||||
|
} else if (playbackState == Player.STATE_BUFFERING) {
|
||||||
|
showBuffering();
|
||||||
|
} else {
|
||||||
|
hideBuffering();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -138,6 +183,12 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
renderClaim();
|
renderClaim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void logUrlEvent(String url) {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("uri", url);
|
||||||
|
LbryAnalytics.logEvent(LbryAnalytics.EVENT_OPEN_FILE_PAGE, bundle);
|
||||||
|
}
|
||||||
|
|
||||||
private void checkAndResetNowPlayingClaim() {
|
private void checkAndResetNowPlayingClaim() {
|
||||||
if (MainActivity.nowPlayingClaim != null &&
|
if (MainActivity.nowPlayingClaim != null &&
|
||||||
!MainActivity.nowPlayingClaim.getClaimId().equalsIgnoreCase(claim.getClaimId())) {
|
!MainActivity.nowPlayingClaim.getClaimId().equalsIgnoreCase(claim.getClaimId())) {
|
||||||
|
@ -164,6 +215,9 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentUrl = newUrl;
|
||||||
|
logUrlEvent(newUrl);
|
||||||
|
resetViewCount();
|
||||||
ClaimCacheKey key = new ClaimCacheKey();
|
ClaimCacheKey key = new ClaimCacheKey();
|
||||||
key.setClaimId(newClaimId);
|
key.setClaimId(newClaimId);
|
||||||
if (!Helper.isNullOrEmpty(newUrl) && newUrl.contains("#")) {
|
if (!Helper.isNullOrEmpty(newUrl) && newUrl.contains("#")) {
|
||||||
|
@ -230,7 +284,7 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildLbryTvStreamingUrl() {
|
private String buildLbryTvStreamingUrl() {
|
||||||
return String.format("https://player.lbry.tv/content/claims/%s/%s/stream", claim.getName(), claim.getClaimId());
|
return String.format("https://cdn.lbryplayer.xyz/content/claims/%s/%s/stream", claim.getName(), claim.getClaimId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadFile() {
|
private void loadFile() {
|
||||||
|
@ -241,7 +295,7 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadFilePending = false;
|
loadFilePending = false;
|
||||||
// TODO: Check if it's paid content and then wait for the user to explicity request the file
|
// TODO: Check if it's paid content and then wait for the user to explicitly request the file
|
||||||
String claimId = claim.getClaimId();
|
String claimId = claim.getClaimId();
|
||||||
FileListTask task = new FileListTask(claimId, null, new FileListTask.FileListResultHandler() {
|
FileListTask task = new FileListTask(claimId, null, new FileListTask.FileListResultHandler() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -257,6 +311,7 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
|
@ -266,6 +321,7 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private void resolveUrl(String url) {
|
private void resolveUrl(String url) {
|
||||||
resolving = true;
|
resolving = true;
|
||||||
|
findViewById(R.id.file_view_claim_display_area).setVisibility(View.INVISIBLE);
|
||||||
View loadingView = findViewById(R.id.file_view_loading_container);
|
View loadingView = findViewById(R.id.file_view_loading_container);
|
||||||
ResolveTask task = new ResolveTask(url, Lbry.LBRY_TV_CONNECTION_STRING, loadingView, new ClaimListResultHandler() {
|
ResolveTask task = new ResolveTask(url, Lbry.LBRY_TV_CONNECTION_STRING, loadingView, new ClaimListResultHandler() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -359,6 +415,18 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
findViewById(R.id.player_toggle_full_screen).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
// check full screen mode
|
||||||
|
if (isInFullscreenMode()) {
|
||||||
|
disableFullScreenMode();
|
||||||
|
} else {
|
||||||
|
enableFullScreenMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
RecyclerView relatedContentList = findViewById(R.id.file_view_related_content_list);
|
RecyclerView relatedContentList = findViewById(R.id.file_view_related_content_list);
|
||||||
relatedContentList.setNestedScrollingEnabled(false);
|
relatedContentList.setNestedScrollingEnabled(false);
|
||||||
LinearLayoutManager llm = new LinearLayoutManager(this);
|
LinearLayoutManager llm = new LinearLayoutManager(this);
|
||||||
|
@ -370,6 +438,8 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadViewCount();
|
||||||
|
|
||||||
((NestedScrollView) findViewById(R.id.file_view_scroll_view)).scrollTo(0, 0);
|
((NestedScrollView) findViewById(R.id.file_view_scroll_view)).scrollTo(0, 0);
|
||||||
findViewById(R.id.file_view_claim_display_area).setVisibility(View.VISIBLE);
|
findViewById(R.id.file_view_claim_display_area).setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
@ -402,27 +472,58 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
descTagsList.setAdapter(tagListAdapter);
|
descTagsList.setAdapter(tagListAdapter);
|
||||||
findViewById(R.id.file_view_tag_area).setVisibility(tags.size() > 0 ? View.VISIBLE : View.GONE);
|
findViewById(R.id.file_view_tag_area).setVisibility(tags.size() > 0 ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
|
findViewById(R.id.file_view_exoplayer_container).setVisibility(View.GONE);
|
||||||
|
findViewById(R.id.file_view_unsupported_container).setVisibility(View.GONE);
|
||||||
|
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())) {
|
||||||
|
ImageView thumbnailView = findViewById(R.id.file_view_thumbnail);
|
||||||
|
Glide.with(getApplicationContext()).load(claim.getThumbnailUrl()).centerCrop().into(thumbnailView);
|
||||||
|
} else {
|
||||||
|
// display first x letters of claim name, with random background
|
||||||
|
}
|
||||||
|
|
||||||
|
findViewById(R.id.file_view_main_action_button).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
onMainActionButtonClicked();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
findViewById(R.id.file_view_media_meta_container).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
onMainActionButtonClicked();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
boolean isFree = true;
|
||||||
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) findViewById(R.id.file_view_publish_time)).setText(DateUtils.getRelativeTimeSpanString(
|
((TextView) 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));
|
||||||
|
|
||||||
// Check the metadata type
|
Fee fee = streamMetadata.getFee();
|
||||||
String mediaType = streamMetadata.getSource().getMediaType();
|
if (fee != null && Helper.parseDouble(fee.getAmount(), 0) > 0) {
|
||||||
// Use Exoplayer view if it's video / audio
|
isFree = false;
|
||||||
if (mediaType.startsWith("audio") || mediaType.startsWith("video")) {
|
findViewById(R.id.file_view_fee_container).setVisibility(View.VISIBLE);
|
||||||
showExoplayerView();
|
((TextView) findViewById(R.id.file_view_fee)).setText(Helper.shortCurrencyFormat(Helper.parseDouble(fee.getAmount(), 0)));
|
||||||
playMedia();
|
|
||||||
} else if (mediaType.startsWith("text")) {
|
|
||||||
|
|
||||||
} else if (mediaType.startsWith("image")) {
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// unsupported type
|
|
||||||
showUnsupportedView();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaterialButton mainActionButton = findViewById(R.id.file_view_main_action_button);
|
||||||
|
String mediaType = streamMetadata.getSource().getMediaType();
|
||||||
|
if (mediaType.startsWith("audio") || mediaType.startsWith("video")) {
|
||||||
|
mainActionButton.setText(R.string.play);
|
||||||
|
} else if (mediaType.startsWith("text") || mediaType.startsWith("image")) {
|
||||||
|
mainActionButton.setText(R.string.view);
|
||||||
|
} else {
|
||||||
|
mainActionButton.setText(R.string.download);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFree) {
|
||||||
|
onMainActionButtonClicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
loadRelatedContent();
|
loadRelatedContent();
|
||||||
|
@ -451,9 +552,7 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerView view = findViewById(R.id.file_view_exoplayer_view);
|
PlayerView view = findViewById(R.id.file_view_exoplayer_view);
|
||||||
PlayerControlView controlView = findViewById(R.id.file_view_exoplayer_control_view);
|
|
||||||
view.setPlayer(MainActivity.appPlayer);
|
view.setPlayer(MainActivity.appPlayer);
|
||||||
controlView.setPlayer(MainActivity.appPlayer);
|
|
||||||
|
|
||||||
if (MainActivity.nowPlayingClaim != null &&
|
if (MainActivity.nowPlayingClaim != null &&
|
||||||
MainActivity.nowPlayingClaim.getClaimId().equalsIgnoreCase(claim.getClaimId()) &&
|
MainActivity.nowPlayingClaim.getClaimId().equalsIgnoreCase(claim.getClaimId()) &&
|
||||||
|
@ -462,6 +561,8 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetPlayer();
|
||||||
|
showBuffering();
|
||||||
MainActivity.setNowPlayingClaim(claim, FileViewActivity.this);
|
MainActivity.setNowPlayingClaim(claim, FileViewActivity.this);
|
||||||
String userAgent = Util.getUserAgent(this, getString(R.string.app_name));
|
String userAgent = Util.getUserAgent(this, getString(R.string.app_name));
|
||||||
MediaSource mediaSource = new ProgressiveMediaSource.Factory(
|
MediaSource mediaSource = new ProgressiveMediaSource.Factory(
|
||||||
|
@ -471,8 +572,81 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
MainActivity.appPlayer.prepare(mediaSource, true, true);
|
MainActivity.appPlayer.prepare(mediaSource, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadViewCount() {
|
private void resetViewCount() {
|
||||||
|
TextView textViewCount = findViewById(R.id.file_view_view_count);
|
||||||
|
Helper.setViewText(textViewCount, null);
|
||||||
|
Helper.setViewVisibility(textViewCount, View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadViewCount() {
|
||||||
|
if (claim != null) {
|
||||||
|
FetchStatCountTask task = new FetchStatCountTask(
|
||||||
|
FetchStatCountTask.STAT_VIEW_COUNT, claim.getClaimId(), null, new FetchStatCountTask.FetchStatCountHandler() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(int count) {
|
||||||
|
try {
|
||||||
|
String displayText = getResources().getQuantityString(R.plurals.view_count, count, NumberFormat.getInstance().format(count));
|
||||||
|
TextView textViewCount = findViewById(R.id.file_view_view_count);
|
||||||
|
Helper.setViewText(textViewCount, displayText);
|
||||||
|
Helper.setViewVisibility(textViewCount, View.VISIBLE);
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception error) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
});
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onMainActionButtonClicked() {
|
||||||
|
// Check if the claim is free
|
||||||
|
Claim.GenericMetadata metadata = claim.getValue();
|
||||||
|
if (metadata instanceof Claim.StreamMetadata) {
|
||||||
|
Claim.StreamMetadata streamMetadata = (Claim.StreamMetadata) metadata;
|
||||||
|
|
||||||
|
Fee fee = streamMetadata.getFee();
|
||||||
|
if (fee != null && Helper.parseDouble(fee.getAmount(), 0) > 0) {
|
||||||
|
// not free, perform a purchase
|
||||||
|
|
||||||
|
} else {
|
||||||
|
handleMainActionForClaim();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showError(getString(R.string.cannot_view_claim));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleMainActionForClaim() {
|
||||||
|
startTimeMillis = System.currentTimeMillis();
|
||||||
|
Claim.GenericMetadata metadata = claim.getValue();
|
||||||
|
if (metadata instanceof Claim.StreamMetadata) {
|
||||||
|
Claim.StreamMetadata streamMetadata = (Claim.StreamMetadata) metadata;
|
||||||
|
// Check the metadata type
|
||||||
|
String mediaType = streamMetadata.getSource().getMediaType();
|
||||||
|
// Use Exoplayer view if it's video / audio
|
||||||
|
if (mediaType.startsWith("audio") || mediaType.startsWith("video")) {
|
||||||
|
showExoplayerView();
|
||||||
|
playMedia();
|
||||||
|
} else if (mediaType.startsWith("text")) {
|
||||||
|
|
||||||
|
} else if (mediaType.startsWith("image")) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// unsupported type
|
||||||
|
showUnsupportedView();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showError(getString(R.string.cannot_view_claim));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showError(String message) {
|
||||||
|
Snackbar.make(findViewById(R.id.file_view_claim_display_area), message, Snackbar.LENGTH_LONG).setBackgroundTint(Color.RED).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadRelatedContent() {
|
private void loadRelatedContent() {
|
||||||
|
@ -524,6 +698,11 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
|
if (isInFullscreenMode()) {
|
||||||
|
disableFullScreenMode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MainActivity.mainActive = true;
|
MainActivity.mainActive = true;
|
||||||
Intent intent = new Intent(this, MainActivity.class);
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
@ -567,16 +746,13 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private void renderPictureInPictureMode() {
|
private void renderPictureInPictureMode() {
|
||||||
findViewById(R.id.file_view_scroll_view).setVisibility(View.GONE);
|
findViewById(R.id.file_view_scroll_view).setVisibility(View.GONE);
|
||||||
findViewById(R.id.file_view_exoplayer_control_view).setVisibility(View.GONE);
|
|
||||||
findViewById(R.id.floating_balance_main_container).setVisibility(View.GONE);
|
findViewById(R.id.floating_balance_main_container).setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
private void renderFullMode() {
|
private void renderFullMode() {
|
||||||
findViewById(R.id.file_view_scroll_view).setVisibility(View.VISIBLE);
|
findViewById(R.id.file_view_scroll_view).setVisibility(View.VISIBLE);
|
||||||
|
if (!isInFullscreenMode()) {
|
||||||
findViewById(R.id.floating_balance_main_container).setVisibility(View.VISIBLE);
|
findViewById(R.id.floating_balance_main_container).setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
PlayerControlView controlView = findViewById(R.id.file_view_exoplayer_control_view);
|
|
||||||
controlView.setPlayer(null);
|
|
||||||
controlView.setPlayer(MainActivity.appPlayer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -587,4 +763,151 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
renderFullMode();
|
renderFullMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
|
private void enableFullScreenMode() {
|
||||||
|
findViewById(R.id.floating_balance_main_container).setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
View decorView = getWindow().getDecorView();
|
||||||
|
decorView.setSystemUiVisibility(
|
||||||
|
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||||
|
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
|
||||||
|
View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||||
|
|
||||||
|
ConstraintLayout globalLayout = findViewById(R.id.file_view_global_layout);
|
||||||
|
View exoplayerContainer = findViewById(R.id.file_view_exoplayer_container);
|
||||||
|
((ViewGroup) exoplayerContainer.getParent()).removeView(exoplayerContainer);
|
||||||
|
globalLayout.addView(exoplayerContainer);
|
||||||
|
|
||||||
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||||
|
((ImageView) findViewById(R.id.player_image_full_screen_toggle)).setImageResource(R.drawable.ic_fullscreen_exit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disableFullScreenMode() {
|
||||||
|
RelativeLayout mediaContainer = findViewById(R.id.file_view_media_container);
|
||||||
|
View exoplayerContainer = findViewById(R.id.file_view_exoplayer_container);
|
||||||
|
((ViewGroup) exoplayerContainer.getParent()).removeView(exoplayerContainer);
|
||||||
|
mediaContainer.addView(exoplayerContainer);
|
||||||
|
|
||||||
|
View decorView = getWindow().getDecorView();
|
||||||
|
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_VISIBLE);
|
||||||
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
|
||||||
|
|
||||||
|
((ImageView) findViewById(R.id.player_image_full_screen_toggle)).setImageResource(R.drawable.ic_fullscreen);
|
||||||
|
findViewById(R.id.floating_balance_main_container).setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInFullscreenMode() {
|
||||||
|
View exoplayerContainer = findViewById(R.id.file_view_exoplayer_container);
|
||||||
|
return exoplayerContainer.getParent() instanceof ConstraintLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleElapsedPlayback() {
|
||||||
|
if (!elapsedPlaybackScheduled) {
|
||||||
|
elapsedPlaybackScheduler = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
elapsedPlaybackScheduler.scheduleAtFixedRate(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (MainActivity.appPlayer != null) {
|
||||||
|
elapsedDuration = MainActivity.appPlayer.getCurrentPosition();
|
||||||
|
renderElapsedDuration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 0, 500, TimeUnit.MILLISECONDS);
|
||||||
|
elapsedPlaybackScheduled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetPlayer() {
|
||||||
|
elapsedDuration = 0;
|
||||||
|
totalDuration = 0;
|
||||||
|
elapsedPlaybackScheduled = false;
|
||||||
|
if (elapsedPlaybackScheduler != null) {
|
||||||
|
elapsedPlaybackScheduler.shutdownNow();
|
||||||
|
elapsedPlaybackScheduler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
playbackStarted = false;
|
||||||
|
startTimeMillis = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showBuffering() {
|
||||||
|
findViewById(R.id.player_buffering_progress).setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideBuffering() {
|
||||||
|
findViewById(R.id.player_buffering_progress).setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderElapsedDuration() {
|
||||||
|
Helper.setViewText(findViewById(R.id.player_duration_elapsed), Helper.formatDuration(Double.valueOf(elapsedDuration / 1000.0).longValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderTotalDuration() {
|
||||||
|
Helper.setViewText(findViewById(R.id.player_duration_total), Helper.formatDuration(Double.valueOf(totalDuration / 1000.0).longValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logPlay(String url, long startTimeMillis) {
|
||||||
|
long timeToStartMillis = startTimeMillis > 0 ? System.currentTimeMillis() - startTimeMillis : 0;
|
||||||
|
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("uri", url);
|
||||||
|
bundle.putLong("time_to_start_ms", timeToStartMillis);
|
||||||
|
bundle.putLong("time_to_start_seconds", Double.valueOf(timeToStartMillis / 1000.0).longValue());
|
||||||
|
LbryAnalytics.logEvent(LbryAnalytics.EVENT_PLAY, bundle);
|
||||||
|
|
||||||
|
logFileView(url, timeToStartMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logFileView(String url, long timeToStart) {
|
||||||
|
if (claim != null) {
|
||||||
|
LogFileViewTask task = new LogFileViewTask(url, claim, timeToStart, new GenericTaskHandler() {
|
||||||
|
@Override
|
||||||
|
public void beforeStart() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess() {
|
||||||
|
claimEligibleRewards();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception error) { }
|
||||||
|
});
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void claimEligibleRewards() {
|
||||||
|
// attempt to claim eligible rewards after viewing or playing a file (fail silently)
|
||||||
|
ClaimRewardTask firstStreamTask = new ClaimRewardTask(Reward.TYPE_FIRST_STREAM, null, null, this, eligibleRewardHandler);
|
||||||
|
ClaimRewardTask dailyViewTask = new ClaimRewardTask(Reward.TYPE_DAILY_VIEW, null, null, this, eligibleRewardHandler);
|
||||||
|
firstStreamTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
dailyViewTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClaimRewardTask.ClaimRewardHandler eligibleRewardHandler = new ClaimRewardTask.ClaimRewardHandler() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(double amountClaimed, String message) {
|
||||||
|
if (Helper.isNullOrEmpty(message)) {
|
||||||
|
message = getResources().getQuantityString(
|
||||||
|
R.plurals.claim_reward_message,
|
||||||
|
amountClaimed == 1 ? 1 : 2,
|
||||||
|
new DecimalFormat(Helper.LBC_CURRENCY_FORMAT_PATTERN).format(amountClaimed));
|
||||||
|
}
|
||||||
|
Snackbar.make(findViewById(R.id.file_view_global_layout), message, Snackbar.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception error) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Html;
|
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -19,6 +18,7 @@ import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
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.Lbryio;
|
import io.lbry.browser.utils.Lbryio;
|
||||||
|
|
||||||
public class FirstRunActivity extends AppCompatActivity {
|
public class FirstRunActivity extends AppCompatActivity {
|
||||||
|
@ -60,6 +60,11 @@ public class FirstRunActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
LbryAnalytics.setCurrentScreen(this, "First Run", "FirstRun");
|
||||||
|
}
|
||||||
|
|
||||||
private void registerAuthReceiver() {
|
private void registerAuthReceiver() {
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(MainActivity.ACTION_USER_AUTHENTICATION_SUCCESS);
|
filter.addAction(MainActivity.ACTION_USER_AUTHENTICATION_SUCCESS);
|
||||||
|
@ -78,8 +83,13 @@ public class FirstRunActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleAuthenticationSuccess() {
|
private void handleAuthenticationSuccess() {
|
||||||
|
|
||||||
// first_auth completed event
|
// first_auth completed event
|
||||||
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
boolean firstAuthCompleted = sp.getBoolean(MainActivity.PREFERENCE_KEY_INTERNAL_FIRST_AUTH_COMPLETED, false);
|
||||||
|
if (!firstAuthCompleted) {
|
||||||
|
LbryAnalytics.logEvent(LbryAnalytics.EVENT_FIRST_USER_AUTH);
|
||||||
|
sp.edit().putBoolean(MainActivity.PREFERENCE_KEY_INTERNAL_FIRST_AUTH_COMPLETED, true).apply();
|
||||||
|
}
|
||||||
|
|
||||||
findViewById(R.id.welcome_wait_container).setVisibility(View.GONE);
|
findViewById(R.id.welcome_wait_container).setVisibility(View.GONE);
|
||||||
findViewById(R.id.welcome_display).setVisibility(View.VISIBLE);
|
findViewById(R.id.welcome_display).setVisibility(View.VISIBLE);
|
||||||
|
@ -96,10 +106,10 @@ public class FirstRunActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private void finishFirstRun() {
|
private void finishFirstRun() {
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
sp.edit().putBoolean(MainActivity.PREFERENCE_KEY_FIRST_RUN_COMPLETED, true).apply();
|
sp.edit().putBoolean(MainActivity.PREFERENCE_KEY_INTERNAL_FIRST_RUN_COMPLETED, true).apply();
|
||||||
|
|
||||||
// first_run_completed event
|
// first_run_completed event
|
||||||
|
LbryAnalytics.logEvent(LbryAnalytics.EVENT_FIRST_RUN_COMPLETED);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
160
app/src/main/java/io/lbry/browser/LbrynetMessagingService.java
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
package io.lbry.browser;
|
||||||
|
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.media.RingtoneManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.core.app.NotificationCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.google.firebase.analytics.FirebaseAnalytics;
|
||||||
|
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||||
|
import com.google.firebase.messaging.RemoteMessage;
|
||||||
|
|
||||||
|
import io.lbry.lbrysdk.LbrynetService;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LbrynetMessagingService extends FirebaseMessagingService {
|
||||||
|
|
||||||
|
private static final String TAG = "LbrynetMessagingService";
|
||||||
|
private static final String NOTIFICATION_CHANNEL_ID = "io.lbry.browser.LBRY_ENGAGEMENT_CHANNEL";
|
||||||
|
private static final String TYPE_SUBSCRIPTION = "subscription";
|
||||||
|
private static final String TYPE_REWARD = "reward";
|
||||||
|
private static final String TYPE_INTERESTS = "interests";
|
||||||
|
private static final String TYPE_CREATOR = "creator";
|
||||||
|
private FirebaseAnalytics firebaseAnalytics;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessageReceived(RemoteMessage remoteMessage) {
|
||||||
|
if (firebaseAnalytics == null) {
|
||||||
|
firebaseAnalytics = FirebaseAnalytics.getInstance(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> payload = remoteMessage.getData();
|
||||||
|
if (payload != null) {
|
||||||
|
String type = payload.get("type");
|
||||||
|
String url = payload.get("target");
|
||||||
|
String title = payload.get("title");
|
||||||
|
String body = payload.get("body");
|
||||||
|
String name = payload.get("name"); // notification name
|
||||||
|
String contentTitle = payload.get("content_title");
|
||||||
|
String channelUrl = payload.get("channel_url");
|
||||||
|
//String publishTime = payload.get("publish_time");
|
||||||
|
String publishTime = null;
|
||||||
|
|
||||||
|
if (type != null && getEnabledTypes().indexOf(type) > -1 && body != null && body.trim().length() > 0) {
|
||||||
|
// only log the receive event for valid notifications received
|
||||||
|
if (firebaseAnalytics != null) {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("name", name);
|
||||||
|
firebaseAnalytics.logEvent("lbry_notification_receive", bundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendNotification(title, body, type, url, name, contentTitle, channelUrl, publishTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewToken(String token) {
|
||||||
|
Log.d(TAG, "Refreshed token: " + token);
|
||||||
|
|
||||||
|
// If you want to send messages to this application instance or
|
||||||
|
// manage this apps subscriptions on the server side, send the
|
||||||
|
// Instance ID token to your app server.
|
||||||
|
sendRegistrationToServer(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persist token to third-party servers.
|
||||||
|
*
|
||||||
|
* Modify this method to associate the user's FCM InstanceID token with any server-side account
|
||||||
|
* maintained by your application.
|
||||||
|
*
|
||||||
|
* @param token The new token.
|
||||||
|
*/
|
||||||
|
private void sendRegistrationToServer(String token) {
|
||||||
|
// TODO: Implement this method to send token to your app server.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and show a simple notification containing the received FCM message.
|
||||||
|
*
|
||||||
|
* @param messageBody FCM message body received.
|
||||||
|
*/
|
||||||
|
private void sendNotification(String title, String messageBody, String type, String url, String name,
|
||||||
|
String contentTitle, String channelUrl, String publishTime) {
|
||||||
|
//Intent intent = new Intent(this, MainActivity.class);
|
||||||
|
//intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
if (url == null) {
|
||||||
|
if (TYPE_REWARD.equals(type)) {
|
||||||
|
url = "lbry://?rewards";
|
||||||
|
} else {
|
||||||
|
// default to home page
|
||||||
|
url = "lbry://?discover";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||||
|
launchIntent.putExtra("notification_name", name);
|
||||||
|
launchIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, launchIntent, PendingIntent.FLAG_ONE_SHOT);
|
||||||
|
|
||||||
|
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
||||||
|
NotificationCompat.Builder notificationBuilder =
|
||||||
|
new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
|
||||||
|
.setColor(ContextCompat.getColor(this, R.color.lbryGreen))
|
||||||
|
.setSmallIcon(R.drawable.ic_lbry)
|
||||||
|
.setContentTitle(title)
|
||||||
|
.setContentText(messageBody)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setSound(defaultSoundUri)
|
||||||
|
.setContentIntent(pendingIntent);
|
||||||
|
|
||||||
|
NotificationManager notificationManager =
|
||||||
|
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
// Since android Oreo notification channel is needed.
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
NotificationChannel channel = new NotificationChannel(
|
||||||
|
NOTIFICATION_CHANNEL_ID, "LBRY Engagement", NotificationManager.IMPORTANCE_DEFAULT);
|
||||||
|
notificationManager.createNotificationChannel(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
notificationManager.notify(3, notificationBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getEnabledTypes() {
|
||||||
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
List<String> enabledTypes = new ArrayList<String>();
|
||||||
|
|
||||||
|
if (sp.getBoolean(MainActivity.PREFERENCE_KEY_NOTIFICATION_SUBSCRIPTIONS, true)) {
|
||||||
|
enabledTypes.add(TYPE_SUBSCRIPTION);
|
||||||
|
}
|
||||||
|
if (sp.getBoolean(MainActivity.PREFERENCE_KEY_NOTIFICATION_REWARDS, true)) {
|
||||||
|
enabledTypes.add(TYPE_REWARD);
|
||||||
|
}
|
||||||
|
if (sp.getBoolean(MainActivity.PREFERENCE_KEY_NOTIFICATION_CONTENT_INTERESTS, true)) {
|
||||||
|
enabledTypes.add(TYPE_INTERESTS);
|
||||||
|
}
|
||||||
|
if (sp.getBoolean(MainActivity.PREFERENCE_KEY_NOTIFICATION_CREATOR, true)) {
|
||||||
|
enabledTypes.add(TYPE_CREATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return enabledTypes;
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,7 +34,11 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||||
import com.google.android.exoplayer2.ui.PlayerView;
|
import com.google.android.exoplayer2.ui.PlayerView;
|
||||||
|
import com.google.android.gms.tasks.OnCompleteListener;
|
||||||
|
import com.google.android.gms.tasks.Task;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
import com.google.firebase.iid.FirebaseInstanceId;
|
||||||
|
import com.google.firebase.iid.InstanceIdResult;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.ActionBar;
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
@ -119,6 +123,7 @@ import io.lbry.browser.ui.wallet.RewardsFragment;
|
||||||
import io.lbry.browser.ui.wallet.WalletFragment;
|
import io.lbry.browser.ui.wallet.WalletFragment;
|
||||||
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.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
import io.lbry.browser.utils.Lbryio;
|
import io.lbry.browser.utils.Lbryio;
|
||||||
import io.lbry.lbrysdk.LbrynetService;
|
import io.lbry.lbrysdk.LbrynetService;
|
||||||
|
@ -136,6 +141,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
public static boolean startingSignInFlowActivity = false;
|
public static boolean startingSignInFlowActivity = false;
|
||||||
public static boolean mainActive = false;
|
public static boolean mainActive = false;
|
||||||
private boolean enteringPIPMode = false;
|
private boolean enteringPIPMode = false;
|
||||||
|
private String firebaseMessagingToken;
|
||||||
|
|
||||||
private Map<String, Fragment> openNavFragments;
|
private Map<String, Fragment> openNavFragments;
|
||||||
private static final Map<Class, Integer> fragmentClassNavIdMap = new HashMap<>();
|
private static final Map<Class, Integer> fragmentClassNavIdMap = new HashMap<>();
|
||||||
|
@ -181,6 +187,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
public static final String PREFERENCE_KEY_NOTIFICATION_SUBSCRIPTIONS = "io.lbry.browser.preference.notifications.Subscriptions";
|
public static final String PREFERENCE_KEY_NOTIFICATION_SUBSCRIPTIONS = "io.lbry.browser.preference.notifications.Subscriptions";
|
||||||
public static final String PREFERENCE_KEY_NOTIFICATION_REWARDS = "io.lbry.browser.preference.notifications.Rewards";
|
public static final String PREFERENCE_KEY_NOTIFICATION_REWARDS = "io.lbry.browser.preference.notifications.Rewards";
|
||||||
public static final String PREFERENCE_KEY_NOTIFICATION_CONTENT_INTERESTS = "io.lbry.browser.preference.notifications.ContentInterests";
|
public static final String PREFERENCE_KEY_NOTIFICATION_CONTENT_INTERESTS = "io.lbry.browser.preference.notifications.ContentInterests";
|
||||||
|
public static final String PREFERENCE_KEY_NOTIFICATION_CREATOR = "io.lbry.browser.preference.notifications.Creator";
|
||||||
public static final String PREFERENCE_KEY_KEEP_SDK_BACKGROUND = "io.lbry.browser.preference.other.KeepSdkInBackground";
|
public static final String PREFERENCE_KEY_KEEP_SDK_BACKGROUND = "io.lbry.browser.preference.other.KeepSdkInBackground";
|
||||||
public static final String PREFERENCE_KEY_PARTICIPATE_DATA_NETWORK = "io.lbry.browser.preference.other.ParticipateInDataNetwork";
|
public static final String PREFERENCE_KEY_PARTICIPATE_DATA_NETWORK = "io.lbry.browser.preference.other.ParticipateInDataNetwork";
|
||||||
|
|
||||||
|
@ -190,9 +197,11 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
public static final String PREFERENCE_KEY_INTERNAL_WALLET_RECEIVE_ADDRESS = "io.lbry.browser.preference.internal.WalletReceiveAddress";
|
public static final String PREFERENCE_KEY_INTERNAL_WALLET_RECEIVE_ADDRESS = "io.lbry.browser.preference.internal.WalletReceiveAddress";
|
||||||
public static final String PREFERENCE_KEY_INTERNAL_REWARDS_NOT_INTERESTED = "io.lbry.browser.preference.internal.RewardsNotInterested";
|
public static final String PREFERENCE_KEY_INTERNAL_REWARDS_NOT_INTERESTED = "io.lbry.browser.preference.internal.RewardsNotInterested";
|
||||||
|
|
||||||
|
public static final String PREFERENCE_KEY_INTERNAL_FIRST_RUN_COMPLETED = "io.lbry.browser.preference.internal.FirstRunCompleted";
|
||||||
|
public static final String PREFERENCE_KEY_INTERNAL_FIRST_AUTH_COMPLETED = "io.lbry.browser.preference.internal.FirstAuthCompleted";
|
||||||
|
|
||||||
private final int CHECK_SDK_READY_INTERVAL = 1000;
|
private final int CHECK_SDK_READY_INTERVAL = 1000;
|
||||||
|
|
||||||
public static final String PREFERENCE_KEY_FIRST_RUN_COMPLETED = "io.lbry.browser.Preference.FirstRunCompleted";
|
|
||||||
public static final String PREFERENCE_KEY_AUTH_TOKEN = "io.lbry.browser.Preference.AuthToken";
|
public static final String PREFERENCE_KEY_AUTH_TOKEN = "io.lbry.browser.Preference.AuthToken";
|
||||||
|
|
||||||
public static final String SECURE_VALUE_KEY_SAVED_PASSWORD = "io.lbry.browser.PX";
|
public static final String SECURE_VALUE_KEY_SAVED_PASSWORD = "io.lbry.browser.PX";
|
||||||
|
@ -273,6 +282,20 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LbryAnalytics.init(this);
|
||||||
|
FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(Task<InstanceIdResult> task) {
|
||||||
|
if (!task.isSuccessful()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get new Instance ID token
|
||||||
|
firebaseMessagingToken = task.getResult().getToken();
|
||||||
|
android.util.Log.d("#HELP", firebaseMessagingToken);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
@ -504,7 +527,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
public static void openFileClaim(Claim claim, Context context) {
|
public static void openFileClaim(Claim claim, Context context) {
|
||||||
Intent intent = new Intent(context, FileViewActivity.class);
|
Intent intent = new Intent(context, FileViewActivity.class);
|
||||||
intent.putExtra("claimId", claim.getClaimId());
|
intent.putExtra("claimId", claim.getClaimId());
|
||||||
intent.putExtra("url", claim.getPermanentUrl());
|
intent.putExtra("url", !Helper.isNullOrEmpty(claim.getShortUrl()) ? claim.getShortUrl() : claim.getPermanentUrl());
|
||||||
startingFileViewActivity = true;
|
startingFileViewActivity = true;
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
|
@ -935,7 +958,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
|
|
||||||
private void checkFirstRun() {
|
private void checkFirstRun() {
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
boolean firstRunCompleted = sp.getBoolean(PREFERENCE_KEY_FIRST_RUN_COMPLETED, false);
|
boolean firstRunCompleted = sp.getBoolean(PREFERENCE_KEY_INTERNAL_FIRST_RUN_COMPLETED, false);
|
||||||
if (!firstRunCompleted) {
|
if (!firstRunCompleted) {
|
||||||
startActivity(new Intent(this, FirstRunActivity.class));
|
startActivity(new Intent(this, FirstRunActivity.class));
|
||||||
} else if (!appStarted) {
|
} else if (!appStarted) {
|
||||||
|
@ -1004,6 +1027,9 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
public void hideFloatingWalletBalance() {
|
public void hideFloatingWalletBalance() {
|
||||||
findViewById(R.id.floating_balance_main_container).setVisibility(View.GONE);
|
findViewById(R.id.floating_balance_main_container).setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
public void hideFloatingRewardsValue() {
|
||||||
|
findViewById(R.id.floating_reward_container).setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
private void initFloatingWalletBalance() {
|
private void initFloatingWalletBalance() {
|
||||||
findViewById(R.id.floating_balance_container).setOnClickListener(new View.OnClickListener() {
|
findViewById(R.id.floating_balance_container).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@ -1455,6 +1481,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
hideActionBar();
|
hideActionBar();
|
||||||
lockDrawer();
|
lockDrawer();
|
||||||
findViewById(R.id.splash_view).setVisibility(View.VISIBLE);
|
findViewById(R.id.splash_view).setVisibility(View.VISIBLE);
|
||||||
|
LbryAnalytics.setCurrentScreen(MainActivity.this, "Splash", "Splash");
|
||||||
}
|
}
|
||||||
protected Boolean doInBackground(Void... params) {
|
protected Boolean doInBackground(Void... params) {
|
||||||
BufferedReader reader = null;
|
BufferedReader reader = null;
|
||||||
|
@ -1547,6 +1574,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
fetchRewards();
|
fetchRewards();
|
||||||
|
|
||||||
checkUrlIntent(getIntent());
|
checkUrlIntent(getIntent());
|
||||||
|
LbryAnalytics.logEvent(LbryAnalytics.EVENT_APP_LAUNCH);
|
||||||
appStarted = true;
|
appStarted = true;
|
||||||
}
|
}
|
||||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
@ -1576,6 +1604,12 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showFloatingUnclaimedRewards() {
|
public void showFloatingUnclaimedRewards() {
|
||||||
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
boolean notInterestedInRewards = sp.getBoolean(PREFERENCE_KEY_INTERNAL_REWARDS_NOT_INTERESTED, false);
|
||||||
|
if (notInterestedInRewards) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
((TextView) findViewById(R.id.floating_reward_value)).setText(Helper.shortCurrencyFormat(Lbryio.totalUnclaimedRewardAmount));
|
((TextView) findViewById(R.id.floating_reward_value)).setText(Helper.shortCurrencyFormat(Lbryio.totalUnclaimedRewardAmount));
|
||||||
findViewById(R.id.floating_reward_container).setVisibility(View.VISIBLE);
|
findViewById(R.id.floating_reward_container).setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import io.lbry.browser.listener.SignInListener;
|
||||||
import io.lbry.browser.listener.WalletSyncListener;
|
import io.lbry.browser.listener.WalletSyncListener;
|
||||||
import io.lbry.browser.model.lbryinc.User;
|
import io.lbry.browser.model.lbryinc.User;
|
||||||
import io.lbry.browser.tasks.lbryinc.FetchCurrentUserTask;
|
import io.lbry.browser.tasks.lbryinc.FetchCurrentUserTask;
|
||||||
|
import io.lbry.browser.utils.LbryAnalytics;
|
||||||
import io.lbry.browser.utils.Lbryio;
|
import io.lbry.browser.utils.Lbryio;
|
||||||
|
|
||||||
public class VerificationActivity extends FragmentActivity implements SignInListener, WalletSyncListener {
|
public class VerificationActivity extends FragmentActivity implements SignInListener, WalletSyncListener {
|
||||||
|
@ -71,6 +72,7 @@ public class VerificationActivity extends FragmentActivity implements SignInList
|
||||||
|
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
LbryAnalytics.setCurrentScreen(this, "Verification", "Verification");
|
||||||
checkFlow();
|
checkFlow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +125,10 @@ public class VerificationActivity extends FragmentActivity implements SignInList
|
||||||
public void onEmailAdded(String email) {
|
public void onEmailAdded(String email) {
|
||||||
this.email = email;
|
this.email = email;
|
||||||
findViewById(R.id.verification_close_button).setVisibility(View.GONE);
|
findViewById(R.id.verification_close_button).setVisibility(View.GONE);
|
||||||
|
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("email", email);
|
||||||
|
LbryAnalytics.logEvent(LbryAnalytics.EVENT_EMAIL_ADDED, bundle);
|
||||||
}
|
}
|
||||||
public void onEmailEdit() {
|
public void onEmailEdit() {
|
||||||
findViewById(R.id.verification_close_button).setVisibility(View.VISIBLE);
|
findViewById(R.id.verification_close_button).setVisibility(View.VISIBLE);
|
||||||
|
@ -131,6 +137,10 @@ public class VerificationActivity extends FragmentActivity implements SignInList
|
||||||
Snackbar.make(findViewById(R.id.verification_pager), R.string.sign_in_successful, Snackbar.LENGTH_LONG).show();
|
Snackbar.make(findViewById(R.id.verification_pager), R.string.sign_in_successful, Snackbar.LENGTH_LONG).show();
|
||||||
sendBroadcast(new Intent(MainActivity.ACTION_USER_SIGN_IN_SUCCESS));
|
sendBroadcast(new Intent(MainActivity.ACTION_USER_SIGN_IN_SUCCESS));
|
||||||
|
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("email", email);
|
||||||
|
LbryAnalytics.logEvent(LbryAnalytics.EVENT_EMAIL_VERIFIED, bundle);
|
||||||
|
|
||||||
if (flow == VERIFICATION_FLOW_SIGN_IN) {
|
if (flow == VERIFICATION_FLOW_SIGN_IN) {
|
||||||
final Intent resultIntent = new Intent();
|
final Intent resultIntent = new Intent();
|
||||||
resultIntent.putExtra("flow", VERIFICATION_FLOW_SIGN_IN);
|
resultIntent.putExtra("flow", VERIFICATION_FLOW_SIGN_IN);
|
||||||
|
@ -206,6 +216,8 @@ public class VerificationActivity extends FragmentActivity implements SignInList
|
||||||
Lbryio.currentUser = user;
|
Lbryio.currentUser = user;
|
||||||
if (user.isIdentityVerified() && user.isRewardApproved()) {
|
if (user.isIdentityVerified() && user.isRewardApproved()) {
|
||||||
// verified for rewards
|
// verified for rewards
|
||||||
|
LbryAnalytics.logEvent(LbryAnalytics.EVENT_REWARD_ELIGIBILITY_COMPLETED);
|
||||||
|
|
||||||
setResult(RESULT_OK);
|
setResult(RESULT_OK);
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -249,6 +249,7 @@ public class Claim {
|
||||||
try {
|
try {
|
||||||
claim.setClaimId(searchResultObject.getString("claimId"));
|
claim.setClaimId(searchResultObject.getString("claimId"));
|
||||||
claim.setName(searchResultObject.getString("name"));
|
claim.setName(searchResultObject.getString("name"));
|
||||||
|
claim.setConfirmations(1);
|
||||||
|
|
||||||
if (claim.getName().startsWith("@")) {
|
if (claim.getName().startsWith("@")) {
|
||||||
claimUri.setChannelClaimId(claim.getClaimId());
|
claimUri.setChannelClaimId(claim.getClaimId());
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package io.lbry.browser.tasks.content;
|
package io.lbry.browser.tasks;
|
||||||
|
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -14,7 +14,6 @@ import java.util.Map;
|
||||||
|
|
||||||
import io.lbry.browser.exceptions.ApiCallException;
|
import io.lbry.browser.exceptions.ApiCallException;
|
||||||
import io.lbry.browser.model.Claim;
|
import io.lbry.browser.model.Claim;
|
||||||
import io.lbry.browser.tasks.GenericTaskHandler;
|
|
||||||
import io.lbry.browser.utils.Helper;
|
import io.lbry.browser.utils.Helper;
|
||||||
import io.lbry.browser.utils.Lbry;
|
import io.lbry.browser.utils.Lbry;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package io.lbry.browser.tasks.content;
|
package io.lbry.browser.tasks;
|
||||||
|
|
||||||
import io.lbry.browser.model.Claim;
|
import io.lbry.browser.model.Claim;
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package io.lbry.browser.tasks.lbryinc;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
import io.lbry.browser.exceptions.LbryioRequestException;
|
||||||
|
import io.lbry.browser.exceptions.LbryioResponseException;
|
||||||
|
import io.lbry.browser.utils.Helper;
|
||||||
|
import io.lbry.browser.utils.Lbryio;
|
||||||
|
|
||||||
|
public class FetchStatCountTask extends AsyncTask<Void, Void, Integer> {
|
||||||
|
public static final int STAT_VIEW_COUNT = 1;
|
||||||
|
public static final int STAT_SUB_COUNT = 2;
|
||||||
|
|
||||||
|
private String claimId;
|
||||||
|
private int stat;
|
||||||
|
private FetchStatCountHandler handler;
|
||||||
|
private View progressView;
|
||||||
|
private Exception error;
|
||||||
|
|
||||||
|
public FetchStatCountTask(int stat, String claimId, View progressView, FetchStatCountHandler handler) {
|
||||||
|
this.stat = stat;
|
||||||
|
this.claimId = claimId;
|
||||||
|
this.progressView = progressView;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onPreExecute() {
|
||||||
|
Helper.setViewVisibility(progressView, View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Integer doInBackground(Void... params) {
|
||||||
|
int count = -1;
|
||||||
|
try {
|
||||||
|
if (stat != STAT_VIEW_COUNT && stat != STAT_SUB_COUNT) {
|
||||||
|
throw new LbryioRequestException("Invalid stat count specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray results = (JSONArray)
|
||||||
|
Lbryio.parseResponse(Lbryio.call(
|
||||||
|
stat == STAT_VIEW_COUNT ? "file" : "subscription",
|
||||||
|
stat == STAT_VIEW_COUNT ? "view_count" : "sub_count",
|
||||||
|
Lbryio.buildSingleParam("claim_id", claimId),
|
||||||
|
Helper.METHOD_GET, null));
|
||||||
|
if (results.length() > 0) {
|
||||||
|
count = results.getInt(0);
|
||||||
|
}
|
||||||
|
} catch (ClassCastException | LbryioRequestException | LbryioResponseException | JSONException ex) {
|
||||||
|
error = ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onPostExecute(Integer count) {
|
||||||
|
Helper.setViewVisibility(progressView, View.GONE);
|
||||||
|
if (handler != null) {
|
||||||
|
if (count > -1) {
|
||||||
|
handler.onSuccess(count);
|
||||||
|
} else {
|
||||||
|
handler.onError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface FetchStatCountHandler {
|
||||||
|
void onSuccess(int count);
|
||||||
|
void onError(Exception error);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package io.lbry.browser.tasks.lbryinc;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import io.lbry.browser.exceptions.LbryioRequestException;
|
||||||
|
import io.lbry.browser.exceptions.LbryioResponseException;
|
||||||
|
import io.lbry.browser.model.Claim;
|
||||||
|
import io.lbry.browser.tasks.GenericTaskHandler;
|
||||||
|
import io.lbry.browser.utils.Lbryio;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class LogFileViewTask extends AsyncTask<Void, Void, Boolean> {
|
||||||
|
private String uri;
|
||||||
|
private Claim claim;
|
||||||
|
private Exception error;
|
||||||
|
private GenericTaskHandler handler;
|
||||||
|
private long timeToStart;
|
||||||
|
|
||||||
|
public LogFileViewTask(String uri, Claim claim, long timeToStart, GenericTaskHandler handler) {
|
||||||
|
this.uri = uri;
|
||||||
|
this.claim = claim;
|
||||||
|
this.timeToStart = timeToStart;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
protected Boolean doInBackground(Void... params) {
|
||||||
|
try {
|
||||||
|
Map<String, String> options = new HashMap<>();
|
||||||
|
options.put("uri", uri);
|
||||||
|
options.put("claim_id", claim.getClaimId());
|
||||||
|
options.put("outpoint", String.format("%s:%d", claim.getTxid(), claim.getNout()));
|
||||||
|
if (timeToStart > 0) {
|
||||||
|
options.put("time_to_start", String.valueOf(timeToStart));
|
||||||
|
}
|
||||||
|
Lbryio.call("file", "view", options, null).close();
|
||||||
|
} catch (LbryioRequestException | LbryioResponseException ex) {
|
||||||
|
error = ex;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
if (handler != null) {
|
||||||
|
if (result) {
|
||||||
|
handler.onSuccess();
|
||||||
|
} else {
|
||||||
|
handler.onError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package io.lbry.browser.tasks.content;
|
package io.lbry.browser.tasks.lbryinc;
|
||||||
|
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
|
|
@ -38,6 +38,7 @@ import io.lbry.browser.tasks.FollowUnfollowTagTask;
|
||||||
import io.lbry.browser.ui.BaseFragment;
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
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.Predefined;
|
import io.lbry.browser.utils.Predefined;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -295,6 +296,10 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
||||||
fetchClaimSearchContent(true);
|
fetchClaimSearchContent(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("tag", tag.getLowercaseName());
|
||||||
|
LbryAnalytics.logEvent(unfollowing ? LbryAnalytics.EVENT_TAG_UNFOLLOW : LbryAnalytics.EVENT_TAG_FOLLOW, bundle);
|
||||||
|
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
((MainActivity) context).saveSharedUserState();
|
((MainActivity) context).saveSharedUserState();
|
||||||
|
@ -359,6 +364,18 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Helper.setWunderbarValue(null, getContext());
|
Helper.setWunderbarValue(null, getContext());
|
||||||
|
checkParams(false);
|
||||||
|
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
if (singleTagView) {
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Tag", "Tag");
|
||||||
|
} else {
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "All Content", "AllContent");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
|
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
|
||||||
updateContentFromLinkText();
|
updateContentFromLinkText();
|
||||||
updateContentScopeLinkText();
|
updateContentScopeLinkText();
|
||||||
|
@ -424,7 +441,8 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
||||||
@Override
|
@Override
|
||||||
public void onClaimClicked(Claim claim) {
|
public void onClaimClicked(Claim claim) {
|
||||||
String claimId = claim.getClaimId();
|
String claimId = claim.getClaimId();
|
||||||
String url = claim.getPermanentUrl();
|
String url = !Helper.isNullOrEmpty(claim.getShortUrl()) ? claim.getShortUrl() : claim.getPermanentUrl();
|
||||||
|
|
||||||
if (claim.getName().startsWith("@")) {
|
if (claim.getName().startsWith("@")) {
|
||||||
// channel claim
|
// channel claim
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
|
|
|
@ -251,7 +251,7 @@ public class ChannelContentFragment extends Fragment implements SharedPreference
|
||||||
@Override
|
@Override
|
||||||
public void onClaimClicked(Claim claim) {
|
public void onClaimClicked(Claim claim) {
|
||||||
String claimId = claim.getClaimId();
|
String claimId = claim.getClaimId();
|
||||||
String url = claim.getPermanentUrl();
|
String url = !Helper.isNullOrEmpty(claim.getShortUrl()) ? claim.getShortUrl() : claim.getPermanentUrl();
|
||||||
if (claim.getName().startsWith("@")) {
|
if (claim.getName().startsWith("@")) {
|
||||||
// channel claim
|
// channel claim
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
|
|
|
@ -42,15 +42,15 @@ import io.lbry.browser.model.Claim;
|
||||||
import io.lbry.browser.model.NavMenuItem;
|
import io.lbry.browser.model.NavMenuItem;
|
||||||
import io.lbry.browser.model.Tag;
|
import io.lbry.browser.model.Tag;
|
||||||
import io.lbry.browser.model.WalletBalance;
|
import io.lbry.browser.model.WalletBalance;
|
||||||
import io.lbry.browser.tasks.GenericTaskHandler;
|
|
||||||
import io.lbry.browser.tasks.UpdateSuggestedTagsTask;
|
import io.lbry.browser.tasks.UpdateSuggestedTagsTask;
|
||||||
import io.lbry.browser.tasks.UploadImageTask;
|
import io.lbry.browser.tasks.UploadImageTask;
|
||||||
import io.lbry.browser.tasks.content.ChannelCreateUpdateTask;
|
import io.lbry.browser.tasks.ChannelCreateUpdateTask;
|
||||||
import io.lbry.browser.tasks.content.ClaimResultHandler;
|
import io.lbry.browser.tasks.ClaimResultHandler;
|
||||||
import io.lbry.browser.tasks.content.LogPublishTask;
|
import io.lbry.browser.tasks.lbryinc.LogPublishTask;
|
||||||
import io.lbry.browser.ui.BaseFragment;
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
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.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -508,6 +508,7 @@ public class ChannelFormFragment extends BaseFragment implements WalletBalanceLi
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
MainActivity activity = (MainActivity) context;
|
MainActivity activity = (MainActivity) context;
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Channel Form", "ChannelForm");
|
||||||
if (editMode) {
|
if (editMode) {
|
||||||
ActionBar actionBar = activity.getSupportActionBar();
|
ActionBar actionBar = activity.getSupportActionBar();
|
||||||
if (actionBar != null) {
|
if (actionBar != null) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import com.google.android.material.tabs.TabLayoutMediator;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -38,11 +39,13 @@ import io.lbry.browser.model.lbryinc.Subscription;
|
||||||
import io.lbry.browser.tasks.lbryinc.ChannelSubscribeTask;
|
import io.lbry.browser.tasks.lbryinc.ChannelSubscribeTask;
|
||||||
import io.lbry.browser.tasks.ClaimListResultHandler;
|
import io.lbry.browser.tasks.ClaimListResultHandler;
|
||||||
import io.lbry.browser.tasks.ResolveTask;
|
import io.lbry.browser.tasks.ResolveTask;
|
||||||
|
import io.lbry.browser.tasks.lbryinc.FetchStatCountTask;
|
||||||
import io.lbry.browser.ui.BaseFragment;
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
import io.lbry.browser.ui.controls.SolidIconView;
|
import io.lbry.browser.ui.controls.SolidIconView;
|
||||||
import io.lbry.browser.ui.following.FollowingFragment;
|
import io.lbry.browser.ui.following.FollowingFragment;
|
||||||
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.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
import io.lbry.browser.utils.Lbryio;
|
import io.lbry.browser.utils.Lbryio;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
@ -68,12 +71,18 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
|
||||||
private View buttonShare;
|
private View buttonShare;
|
||||||
private View buttonTip;
|
private View buttonTip;
|
||||||
private View buttonFollowUnfollow;
|
private View buttonFollowUnfollow;
|
||||||
|
private int subCount;
|
||||||
private SolidIconView iconFollowUnfollow;
|
private SolidIconView iconFollowUnfollow;
|
||||||
|
|
||||||
|
private View layoutNothingAtLocation;
|
||||||
|
private View layoutLoadingState;
|
||||||
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
ViewGroup container, Bundle savedInstanceState) {
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
View root = inflater.inflate(R.layout.fragment_channel, container, false);
|
View root = inflater.inflate(R.layout.fragment_channel, container, false);
|
||||||
|
|
||||||
|
layoutLoadingState = root.findViewById(R.id.channel_view_loading_state);
|
||||||
|
layoutNothingAtLocation = root.findViewById(R.id.container_nothing_at_location);
|
||||||
layoutDisplayArea = root.findViewById(R.id.channel_view_claim_display_area);
|
layoutDisplayArea = root.findViewById(R.id.channel_view_claim_display_area);
|
||||||
layoutResolving = root.findViewById(R.id.channel_view_loading_container);
|
layoutResolving = root.findViewById(R.id.channel_view_loading_container);
|
||||||
|
|
||||||
|
@ -244,12 +253,13 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
|
|
||||||
Map<String, Object> params = getParams();
|
Map<String, Object> params = getParams();
|
||||||
String url = params != null && params.containsKey("url") ? (String) params.get("url") : null;
|
String url = params != null && params.containsKey("url") ? (String) params.get("url") : null;
|
||||||
Helper.setWunderbarValue(url, context);
|
Helper.setWunderbarValue(url, context);
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
((MainActivity) context).addFetchChannelsListener(this);
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.addFetchChannelsListener(this);
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Channel", "Channel");
|
||||||
}
|
}
|
||||||
|
|
||||||
checkParams();
|
checkParams();
|
||||||
|
@ -284,6 +294,7 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (updateRequired) {
|
if (updateRequired) {
|
||||||
|
resetSubCount();
|
||||||
if (!Helper.isNullOrEmpty(url)) {
|
if (!Helper.isNullOrEmpty(url)) {
|
||||||
resolveUrl();
|
resolveUrl();
|
||||||
} else if (claim == null) {
|
} else if (claim == null) {
|
||||||
|
@ -302,7 +313,7 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
|
||||||
ResolveTask task = new ResolveTask(url, Lbry.LBRY_TV_CONNECTION_STRING, layoutResolving, new ClaimListResultHandler() {
|
ResolveTask task = new ResolveTask(url, Lbry.LBRY_TV_CONNECTION_STRING, layoutResolving, new ClaimListResultHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<Claim> claims) {
|
public void onSuccess(List<Claim> claims) {
|
||||||
if (claims.size() > 0) {
|
if (claims.size() > 0 && !Helper.isNullOrEmpty(claims.get(0).getClaimId())) {
|
||||||
claim = claims.get(0);
|
claim = claims.get(0);
|
||||||
renderClaim();
|
renderClaim();
|
||||||
checkOwnChannel();
|
checkOwnChannel();
|
||||||
|
@ -320,7 +331,9 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderNothingAtLocation() {
|
private void renderNothingAtLocation() {
|
||||||
|
layoutLoadingState.setVisibility(View.VISIBLE);
|
||||||
|
layoutNothingAtLocation.setVisibility(View.VISIBLE);
|
||||||
|
layoutDisplayArea.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParams(Map<String, Object> params) {
|
public void setParams(Map<String, Object> params) {
|
||||||
|
@ -336,7 +349,9 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadSubCount();
|
||||||
checkIsFollowing();
|
checkIsFollowing();
|
||||||
|
layoutLoadingState.setVisibility(View.GONE);
|
||||||
layoutDisplayArea.setVisibility(View.VISIBLE);
|
layoutDisplayArea.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
String thumbnailUrl = claim.getThumbnailUrl();
|
String thumbnailUrl = claim.getThumbnailUrl();
|
||||||
|
@ -376,6 +391,36 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
|
||||||
}).attach();
|
}).attach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resetSubCount() {
|
||||||
|
subCount = -1;
|
||||||
|
Helper.setViewText(textFollowerCount, null);
|
||||||
|
Helper.setViewVisibility(textFollowerCount, View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSubCount() {
|
||||||
|
if (claim != null) {
|
||||||
|
FetchStatCountTask task = new FetchStatCountTask(
|
||||||
|
FetchStatCountTask.STAT_SUB_COUNT, claim.getClaimId(), null, new FetchStatCountTask.FetchStatCountHandler() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(int count) {
|
||||||
|
try {
|
||||||
|
String displayText = getResources().getQuantityString(R.plurals.follower_count, count, NumberFormat.getInstance().format(count));
|
||||||
|
Helper.setViewText(textFollowerCount, displayText);
|
||||||
|
Helper.setViewVisibility(textFollowerCount, View.VISIBLE);
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception error) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
});
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class ChannelPagerAdapter extends FragmentStateAdapter {
|
private static class ChannelPagerAdapter extends FragmentStateAdapter {
|
||||||
private Claim channelClaim;
|
private Claim channelClaim;
|
||||||
public ChannelPagerAdapter(Claim channelClaim, FragmentActivity activity) {
|
public ChannelPagerAdapter(Claim channelClaim, FragmentActivity activity) {
|
||||||
|
|
|
@ -40,6 +40,7 @@ import io.lbry.browser.tasks.ClaimListTask;
|
||||||
import io.lbry.browser.ui.BaseFragment;
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
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;
|
||||||
|
|
||||||
public class ChannelManagerFragment extends BaseFragment implements ActionMode.Callback, SelectionModeListener, SdkStatusListener {
|
public class ChannelManagerFragment extends BaseFragment implements ActionMode.Callback, SelectionModeListener, SdkStatusListener {
|
||||||
|
|
||||||
|
@ -109,7 +110,9 @@ public class ChannelManagerFragment extends BaseFragment implements ActionMode.C
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
((MainActivity) context).setWunderbarValue(null);
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.setWunderbarValue(null);
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Channel Manager", "ChannelManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Lbry.SDK_READY) {
|
if (!Lbry.SDK_READY) {
|
||||||
|
|
|
@ -34,6 +34,7 @@ import io.lbry.browser.tasks.ClaimSearchTask;
|
||||||
import io.lbry.browser.ui.BaseFragment;
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
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.Predefined;
|
import io.lbry.browser.utils.Predefined;
|
||||||
|
|
||||||
public class EditorsChoiceFragment extends BaseFragment {
|
public class EditorsChoiceFragment extends BaseFragment {
|
||||||
|
@ -86,7 +87,13 @@ public class EditorsChoiceFragment extends BaseFragment {
|
||||||
|
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Helper.setWunderbarValue(null, getContext());
|
Context context = getContext();
|
||||||
|
Helper.setWunderbarValue(null, context);
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Editor's Choice", "EditorsChoice");
|
||||||
|
}
|
||||||
|
|
||||||
if (contentListAdapter == null || contentListAdapter.getItemCount() == 0) {
|
if (contentListAdapter == null || contentListAdapter.getItemCount() == 0) {
|
||||||
fetchClaimSearchContent();
|
fetchClaimSearchContent();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -46,6 +46,7 @@ import io.lbry.browser.listener.ChannelItemSelectionListener;
|
||||||
import io.lbry.browser.ui.BaseFragment;
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
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.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
import io.lbry.browser.utils.Lbryio;
|
import io.lbry.browser.utils.Lbryio;
|
||||||
import io.lbry.browser.utils.Predefined;
|
import io.lbry.browser.utils.Predefined;
|
||||||
|
@ -327,8 +328,13 @@ public class FollowingFragment extends BaseFragment implements
|
||||||
|
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Helper.setWunderbarValue(null, getContext());
|
Context context = getContext();
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
|
Helper.setWunderbarValue(null, context);
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context).registerOnSharedPreferenceChangeListener(this);
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Subscriptions", "Subscriptions");
|
||||||
|
}
|
||||||
|
|
||||||
// check if subscriptions exist
|
// check if subscriptions exist
|
||||||
if (suggestedChannelAdapter != null) {
|
if (suggestedChannelAdapter != null) {
|
||||||
|
@ -562,7 +568,7 @@ public class FollowingFragment extends BaseFragment implements
|
||||||
@Override
|
@Override
|
||||||
public void onClaimClicked(Claim claim) {
|
public void onClaimClicked(Claim claim) {
|
||||||
String claimId = claim.getClaimId();
|
String claimId = claim.getClaimId();
|
||||||
String url = claim.getPermanentUrl();
|
String url = !Helper.isNullOrEmpty(claim.getShortUrl()) ? claim.getShortUrl() : claim.getPermanentUrl();
|
||||||
|
|
||||||
if (claim.getName().startsWith("@")) {
|
if (claim.getName().startsWith("@")) {
|
||||||
// channel claim
|
// channel claim
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.lbry.browser.ui.search;
|
package io.lbry.browser.ui.search;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -28,6 +29,7 @@ import io.lbry.browser.tasks.ResolveTask;
|
||||||
import io.lbry.browser.ui.BaseFragment;
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
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.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@ -87,9 +89,15 @@ public class SearchFragment extends BaseFragment implements
|
||||||
|
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Helper.setWunderbarValue(currentQuery, getContext());
|
Context context = getContext();
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
|
Helper.setWunderbarValue(currentQuery, context);
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context).registerOnSharedPreferenceChangeListener(this);
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Search", "Search");
|
||||||
|
}
|
||||||
if (!Helper.isNullOrEmpty(currentQuery)) {
|
if (!Helper.isNullOrEmpty(currentQuery)) {
|
||||||
|
logSearch(currentQuery);
|
||||||
search(currentQuery, currentFrom);
|
search(currentQuery, currentFrom);
|
||||||
} else {
|
} else {
|
||||||
noQueryView.setVisibility(View.VISIBLE);
|
noQueryView.setVisibility(View.VISIBLE);
|
||||||
|
@ -170,17 +178,28 @@ public class SearchFragment extends BaseFragment implements
|
||||||
unresolved.setValue(resolved.getValue());
|
unresolved.setValue(resolved.getValue());
|
||||||
unresolved.setSigningChannel(resolved.getSigningChannel());
|
unresolved.setSigningChannel(resolved.getSigningChannel());
|
||||||
unresolved.setUnresolved(false);
|
unresolved.setUnresolved(false);
|
||||||
|
unresolved.setConfirmations(resolved.getConfirmations());
|
||||||
|
|
||||||
resultListAdapter.notifyDataSetChanged();
|
resultListAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void logSearch(String query) {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("query", query);
|
||||||
|
LbryAnalytics.logEvent(LbryAnalytics.EVENT_SEARCH, bundle);
|
||||||
|
}
|
||||||
|
|
||||||
public void search(String query, int from) {
|
public void search(String query, int from) {
|
||||||
boolean queryChanged = checkQuery(query);
|
boolean queryChanged = checkQuery(query);
|
||||||
if (!queryChanged && from > 0) {
|
if (!queryChanged && from > 0) {
|
||||||
currentFrom = from;
|
currentFrom = from;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (queryChanged) {
|
||||||
|
logSearch(query);
|
||||||
|
}
|
||||||
|
|
||||||
searchLoading = true;
|
searchLoading = true;
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||||
boolean canShowMatureContent = sp.getBoolean(MainActivity.PREFERENCE_KEY_SHOW_MATURE_CONTENT, false);
|
boolean canShowMatureContent = sp.getBoolean(MainActivity.PREFERENCE_KEY_SHOW_MATURE_CONTENT, false);
|
||||||
|
|
|
@ -11,6 +11,7 @@ import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
import io.lbry.browser.MainActivity;
|
import io.lbry.browser.MainActivity;
|
||||||
import io.lbry.browser.R;
|
import io.lbry.browser.R;
|
||||||
|
import io.lbry.browser.utils.LbryAnalytics;
|
||||||
|
|
||||||
public class SettingsFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class SettingsFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,7 +39,12 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
|
Context context = getContext();
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context).registerOnSharedPreferenceChangeListener(this);
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Settings", "Settings");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
|
|
|
@ -41,15 +41,16 @@ import io.lbry.browser.model.lbryinc.Invitee;
|
||||||
import io.lbry.browser.tasks.ClaimListResultHandler;
|
import io.lbry.browser.tasks.ClaimListResultHandler;
|
||||||
import io.lbry.browser.tasks.ClaimListTask;
|
import io.lbry.browser.tasks.ClaimListTask;
|
||||||
import io.lbry.browser.tasks.GenericTaskHandler;
|
import io.lbry.browser.tasks.GenericTaskHandler;
|
||||||
import io.lbry.browser.tasks.content.ChannelCreateUpdateTask;
|
import io.lbry.browser.tasks.ChannelCreateUpdateTask;
|
||||||
import io.lbry.browser.tasks.content.ClaimResultHandler;
|
import io.lbry.browser.tasks.ClaimResultHandler;
|
||||||
import io.lbry.browser.tasks.content.LogPublishTask;
|
import io.lbry.browser.tasks.lbryinc.LogPublishTask;
|
||||||
import io.lbry.browser.tasks.lbryinc.FetchInviteStatusTask;
|
import io.lbry.browser.tasks.lbryinc.FetchInviteStatusTask;
|
||||||
import io.lbry.browser.tasks.lbryinc.FetchReferralCodeTask;
|
import io.lbry.browser.tasks.lbryinc.FetchReferralCodeTask;
|
||||||
import io.lbry.browser.tasks.lbryinc.InviteByEmailTask;
|
import io.lbry.browser.tasks.lbryinc.InviteByEmailTask;
|
||||||
import io.lbry.browser.ui.BaseFragment;
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
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.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
import io.lbry.browser.utils.Lbryio;
|
import io.lbry.browser.utils.Lbryio;
|
||||||
|
|
||||||
|
@ -287,9 +288,14 @@ public class InvitesFragment extends BaseFragment implements SdkStatusListener,
|
||||||
super.onResume();
|
super.onResume();
|
||||||
layoutAccountDriver.setVisibility(Lbryio.isSignedIn() ? View.GONE : View.VISIBLE);
|
layoutAccountDriver.setVisibility(Lbryio.isSignedIn() ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Invites", "Invites");
|
||||||
|
}
|
||||||
|
|
||||||
fetchInviteStatus();
|
fetchInviteStatus();
|
||||||
if (!Lbry.SDK_READY) {
|
if (!Lbry.SDK_READY) {
|
||||||
Context context = getContext();
|
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
MainActivity activity = (MainActivity) context;
|
MainActivity activity = (MainActivity) context;
|
||||||
activity.addSdkStatusListener(this);
|
activity.addSdkStatusListener(this);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.lbry.browser.ui.wallet;
|
package io.lbry.browser.ui.wallet;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
@ -13,6 +14,7 @@ import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.preference.PreferenceManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
@ -32,6 +34,7 @@ import io.lbry.browser.tasks.lbryinc.FetchRewardsTask;
|
||||||
import io.lbry.browser.ui.BaseFragment;
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
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.Lbryio;
|
import io.lbry.browser.utils.Lbryio;
|
||||||
|
|
||||||
public class RewardsFragment extends BaseFragment implements RewardListAdapter.RewardClickListener, SdkStatusListener {
|
public class RewardsFragment extends BaseFragment implements RewardListAdapter.RewardClickListener, SdkStatusListener {
|
||||||
|
@ -87,8 +90,13 @@ public class RewardsFragment extends BaseFragment implements RewardListAdapter.R
|
||||||
checkRewardsStatus();
|
checkRewardsStatus();
|
||||||
fetchRewards();
|
fetchRewards();
|
||||||
|
|
||||||
if (!Lbry.SDK_READY) {
|
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Rewards", "Rewards");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Lbry.SDK_READY) {
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
MainActivity activity = (MainActivity) context;
|
MainActivity activity = (MainActivity) context;
|
||||||
activity.addSdkStatusListener(this);
|
activity.addSdkStatusListener(this);
|
||||||
|
@ -161,9 +169,17 @@ public class RewardsFragment extends BaseFragment implements RewardListAdapter.R
|
||||||
linkNotInterested.setOnClickListener(new View.OnClickListener() {
|
linkNotInterested.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
|
|
||||||
|
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
|
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
((MainActivity) context).onBackPressed();
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
sp.edit().putBoolean(MainActivity.PREFERENCE_KEY_INTERNAL_REWARDS_NOT_INTERESTED, true).apply();
|
||||||
|
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.hideFloatingRewardsValue();
|
||||||
|
activity.onBackPressed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -210,6 +226,7 @@ public class RewardsFragment extends BaseFragment implements RewardListAdapter.R
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateUnclaimedRewardsValue() {
|
public void updateUnclaimedRewardsValue() {
|
||||||
|
try {
|
||||||
String accountDriverTitle = getResources().getQuantityString(
|
String accountDriverTitle = getResources().getQuantityString(
|
||||||
R.plurals.available_credits,
|
R.plurals.available_credits,
|
||||||
Lbryio.totalUnclaimedRewardAmount == 1 ? 1 : 2,
|
Lbryio.totalUnclaimedRewardAmount == 1 ? 1 : 2,
|
||||||
|
@ -217,6 +234,9 @@ public class RewardsFragment extends BaseFragment implements RewardListAdapter.R
|
||||||
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.USD_CURRENCY_FORMAT.format(unclaimedRewardAmountUsd)));
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,6 +23,7 @@ import io.lbry.browser.model.Transaction;
|
||||||
import io.lbry.browser.tasks.wallet.TransactionListTask;
|
import io.lbry.browser.tasks.wallet.TransactionListTask;
|
||||||
import io.lbry.browser.ui.BaseFragment;
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
import io.lbry.browser.utils.Helper;
|
import io.lbry.browser.utils.Helper;
|
||||||
|
import io.lbry.browser.utils.LbryAnalytics;
|
||||||
import io.lbry.browser.utils.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
|
|
||||||
public class TransactionHistoryFragment extends BaseFragment implements TransactionListAdapter.TransactionClickListener {
|
public class TransactionHistoryFragment extends BaseFragment implements TransactionListAdapter.TransactionClickListener {
|
||||||
|
@ -77,6 +78,12 @@ public class TransactionHistoryFragment extends BaseFragment implements Transact
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Transaction History", "TransactionHistory");
|
||||||
|
}
|
||||||
|
|
||||||
if (adapter != null && adapter.getItemCount() > 0 && transactionList != null) {
|
if (adapter != null && adapter.getItemCount() > 0 && transactionList != null) {
|
||||||
transactionList.setAdapter(adapter);
|
transactionList.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ import io.lbry.browser.tasks.wallet.WalletSendTask;
|
||||||
import io.lbry.browser.ui.BaseFragment;
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
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.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
import io.lbry.browser.utils.Lbryio;
|
import io.lbry.browser.utils.Lbryio;
|
||||||
|
|
||||||
|
@ -393,9 +394,14 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
|
||||||
|
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Helper.setWunderbarValue(null, getContext());
|
|
||||||
if (!Lbry.SDK_READY) {
|
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
|
Helper.setWunderbarValue(null, context);
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Wallet", "Wallet");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Lbry.SDK_READY) {
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
MainActivity activity = (MainActivity) context;
|
MainActivity activity = (MainActivity) context;
|
||||||
activity.addSdkStatusListener(this);
|
activity.addSdkStatusListener(this);
|
||||||
|
|
53
app/src/main/java/io/lbry/browser/utils/LbryAnalytics.java
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package io.lbry.browser.utils;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.google.firebase.analytics.FirebaseAnalytics;
|
||||||
|
|
||||||
|
public class LbryAnalytics {
|
||||||
|
|
||||||
|
public static final String EVENT_APP_EXCEPTION = "app_exception";
|
||||||
|
public static final String EVENT_APP_LAUNCH = "app_launch";
|
||||||
|
public static final String EVENT_EMAIL_ADDED = "email_added";
|
||||||
|
public static final String EVENT_EMAIL_VERIFIED = "email_verified";
|
||||||
|
public static final String EVENT_FIRST_RUN_COMPLETED = "first_run_completed";
|
||||||
|
public static final String EVENT_FIRST_USER_AUTH = "first_user_auth";
|
||||||
|
public static final String EVENT_LBRY_NOTIFICATION_OPEN = "lbry_notification_open";
|
||||||
|
public static final String EVENT_LBRY_NOTIFICATION_RECEIVE = "lbry_notification_receive";
|
||||||
|
public static final String EVENT_OPEN_FILE_PAGE = "open_file_page";
|
||||||
|
public static final String EVENT_PLAY = "play";
|
||||||
|
public static final String EVENT_PURCHASE_URI = "purchase_uri";
|
||||||
|
public static final String EVENT_REWARD_ELIGIBILITY_COMPLETED = "reward_eligibility_completed";
|
||||||
|
public static final String EVENT_TAG_FOLLOW = "tag_follow";
|
||||||
|
public static final String EVENT_TAG_UNFOLLOW = "tag_unfollow";
|
||||||
|
public static final String EVENT_PUBLISH = "publish";
|
||||||
|
public static final String EVENT_CHANNEL_CREATE = "channel_create";
|
||||||
|
public static final String EVENT_SEARCH = "search";
|
||||||
|
|
||||||
|
private static FirebaseAnalytics analytics;
|
||||||
|
|
||||||
|
public static void init(Context context) {
|
||||||
|
analytics = FirebaseAnalytics.getInstance(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setCurrentScreen(Activity activity, String name, String className) {
|
||||||
|
analytics.setCurrentScreen(activity, name, className);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void logEvent(String name) {
|
||||||
|
logEvent(name, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void logEvent(String name, Bundle bundle) {
|
||||||
|
analytics.logEvent(name, bundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void logException(String message, String exceptionName) {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("message", message);
|
||||||
|
bundle.putString("name", exceptionName);
|
||||||
|
logEvent("app_exception", bundle);
|
||||||
|
}
|
||||||
|
}
|
11
app/src/main/res/drawable-anydpi/ic_fullscreen.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="M7,14L5,14v5h5v-2L7,17v-3zM5,10h2L7,7h3L10,5L5,5v5zM17,17h-3v2h5v-5h-2v3zM14,5v2h3v3h2L19,5h-5z"/>
|
||||||
|
</vector>
|
11
app/src/main/res/drawable-anydpi/ic_fullscreen_exit.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="M5,16h3v3h2v-5L5,14v2zM8,8L5,8v2h5L10,5L8,5v3zM14,19h2v-3h3v-2h-5v5zM16,8L16,5h-2v5h5L19,8h-3z"/>
|
||||||
|
</vector>
|
BIN
app/src/main/res/drawable-hdpi/ic_fullscreen.png
Normal file
After Width: | Height: | Size: 148 B |
BIN
app/src/main/res/drawable-hdpi/ic_fullscreen_exit.png
Normal file
After Width: | Height: | Size: 138 B |
BIN
app/src/main/res/drawable-mdpi/ic_fullscreen.png
Normal file
After Width: | Height: | Size: 102 B |
BIN
app/src/main/res/drawable-mdpi/ic_fullscreen_exit.png
Normal file
After Width: | Height: | Size: 105 B |
BIN
app/src/main/res/drawable-xhdpi/ic_fullscreen.png
Normal file
After Width: | Height: | Size: 129 B |
BIN
app/src/main/res/drawable-xhdpi/ic_fullscreen_exit.png
Normal file
After Width: | Height: | Size: 132 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_fullscreen.png
Normal file
After Width: | Height: | Size: 155 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_fullscreen_exit.png
Normal file
After Width: | Height: | Size: 160 B |
|
@ -4,9 +4,9 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/pageBackground"
|
android:background="@color/pageBackground">
|
||||||
android:fitsSystemWindows="true">
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/file_view_global_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
@ -42,19 +42,60 @@
|
||||||
android:layout_weight="10"
|
android:layout_weight="10"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:visibility="visible">
|
android:visibility="invisible">
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/file_view_media_container"
|
android:id="@+id/file_view_media_container"
|
||||||
android:background="@color/mediaContainerBackground"
|
android:background="@color/mediaContainerBackground"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="3.25">
|
android:layout_weight="3.25">
|
||||||
<!--RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/file_view_media_meta_container"
|
android:id="@+id/file_view_media_meta_container"
|
||||||
|
android:clickable="true"
|
||||||
|
android:foreground="?attr/selectableItemBackground"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
<ImageView
|
||||||
</RelativeLayout-->
|
android:id="@+id/file_view_thumbnail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/file_view_main_action_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:text="@string/play" />
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/file_view_fee_container"
|
||||||
|
android:background="@drawable/bg_stream_cost"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginRight="4dp"
|
||||||
|
android:paddingTop="2dp"
|
||||||
|
android:paddingBottom="2dp"
|
||||||
|
android:paddingLeft="6dp"
|
||||||
|
android:paddingRight="7dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
<io.lbry.browser.ui.controls.SolidIconView
|
||||||
|
android:layout_width="12dp"
|
||||||
|
android:layout_height="12dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:textSize="8dp"
|
||||||
|
android:text="@string/fa_coins" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/file_view_fee"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginLeft="1dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textFontWeight="300" />
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/file_view_exoplayer_container"
|
android:id="@+id/file_view_exoplayer_container"
|
||||||
|
@ -65,12 +106,8 @@
|
||||||
<com.google.android.exoplayer2.ui.PlayerView
|
<com.google.android.exoplayer2.ui.PlayerView
|
||||||
android:id="@+id/file_view_exoplayer_view"
|
android:id="@+id/file_view_exoplayer_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent"
|
||||||
<com.google.android.exoplayer2.ui.PlayerControlView
|
app:controller_layout_id="@layout/exo_playback_control_view"/>
|
||||||
android:id="@+id/file_view_exoplayer_control_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentBottom="true" />
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
@ -155,7 +192,7 @@
|
||||||
android:id="@+id/file_view_view_count"
|
android:id="@+id/file_view_view_count"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginRight="24dp"
|
android:layout_marginRight="16dp"
|
||||||
android:fontFamily="@font/inter"
|
android:fontFamily="@font/inter"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
android:textFontWeight="300"
|
android:textFontWeight="300"
|
||||||
|
|
41
app/src/main/res/layout/container_nothing_at_location.xml
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/container_nothing_at_location"
|
||||||
|
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/nothing_at_this_location"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/nothing_at_location_publish_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:text="@string/publish_something_here"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
86
app/src/main/res/layout/exo_playback_control_view.xml
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
<?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:background="@color/playerControlsBackground"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_play"
|
||||||
|
android:layout_width="128dp"
|
||||||
|
android:layout_height="128dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
style="@style/ExoMediaButton.Play" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@id/exo_pause"
|
||||||
|
android:layout_width="128dp"
|
||||||
|
android:layout_height="128dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
style="@style/ExoMediaButton.Pause" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/player_buffering_progress"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/player_toggle_full_screen"
|
||||||
|
android:clickable="true"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_alignParentRight="true">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/player_image_full_screen_toggle"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:src="@drawable/ic_fullscreen"
|
||||||
|
android:tint="@color/white" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_toLeftOf="@id/player_toggle_full_screen"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="4dp">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/player_duration_elapsed"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/zero_duration"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
<com.google.android.exoplayer2.ui.DefaultTimeBar
|
||||||
|
android:id="@id/exo_progress"
|
||||||
|
android:layout_toLeftOf="@id/player_duration_total"
|
||||||
|
android:layout_toRightOf="@id/player_duration_elapsed"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
app:scrubber_color="@color/scrubberColor"
|
||||||
|
app:played_color="@color/playedColor"
|
||||||
|
app:buffered_color="@color/bufferedColor" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/player_duration_total"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/zero_duration"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
</RelativeLayout>
|
|
@ -30,6 +30,8 @@
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textFontWeight="300" />
|
android:textFontWeight="300" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<include layout="@layout/container_nothing_at_location" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -73,7 +75,8 @@
|
||||||
android:visibility="invisible"
|
android:visibility="invisible"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="2dp"
|
||||||
|
android:layout_marginBottom="2dp"
|
||||||
android:paddingLeft="4dp"
|
android:paddingLeft="4dp"
|
||||||
android:paddingRight="4dp"
|
android:paddingRight="4dp"
|
||||||
android:paddingTop="2dp"
|
android:paddingTop="2dp"
|
||||||
|
|
|
@ -14,6 +14,11 @@
|
||||||
<color name="channelCoverBackground">#CC000000</color>
|
<color name="channelCoverBackground">#CC000000</color>
|
||||||
<color name="costBackground">#F4E866</color>
|
<color name="costBackground">#F4E866</color>
|
||||||
|
|
||||||
|
<color name="playerControlsBackground">#33000000</color>
|
||||||
|
<color name="scrubberColor">@color/nextLbryGreen</color>
|
||||||
|
<color name="playedColor">@color/nextLbryGreen</color>
|
||||||
|
<color name="bufferedColor">@color/nextLbryGreenSemiTransparent</color>
|
||||||
|
|
||||||
<!-- At some point, these colours have to be renamed -->
|
<!-- At some point, these colours have to be renamed -->
|
||||||
<color name="darkForeground">#EEEEEE</color>
|
<color name="darkForeground">#EEEEEE</color>
|
||||||
<color name="lightForeground">#555555</color>
|
<color name="lightForeground">#555555</color>
|
||||||
|
|
|
@ -14,6 +14,11 @@
|
||||||
<color name="channelCoverBackground">#CC000000</color>
|
<color name="channelCoverBackground">#CC000000</color>
|
||||||
<color name="costBackground">#F4E866</color>
|
<color name="costBackground">#F4E866</color>
|
||||||
|
|
||||||
|
<color name="playerControlsBackground">#33000000</color>
|
||||||
|
<color name="scrubberColor">@color/nextLbryGreen</color>
|
||||||
|
<color name="playedColor">@color/nextLbryGreen</color>
|
||||||
|
<color name="bufferedColor">@color/nextLbryGreenSemiTransparent</color>
|
||||||
|
|
||||||
<color name="darkForeground">#222222</color>
|
<color name="darkForeground">#222222</color>
|
||||||
<color name="lightForeground">#AAAAAA</color>
|
<color name="lightForeground">#AAAAAA</color>
|
||||||
<color name="foreground">#333333</color>
|
<color name="foreground">#333333</color>
|
||||||
|
|
|
@ -59,15 +59,28 @@
|
||||||
<string name="loading_decentralized_data">Loading decentralized data...</string>
|
<string name="loading_decentralized_data">Loading decentralized data...</string>
|
||||||
<string name="related_content">Related Content</string>
|
<string name="related_content">Related Content</string>
|
||||||
<string name="share_lbry_content">Share LBRY content</string>
|
<string name="share_lbry_content">Share LBRY content</string>
|
||||||
|
<string name="view">View</string>
|
||||||
|
<string name="play">Play</string>
|
||||||
|
<plurals name="view_count">
|
||||||
|
<item quantity="one">%1$s view</item>
|
||||||
|
<item quantity="other">%1$s views</item>
|
||||||
|
</plurals>
|
||||||
<string name="unsupported_content">Unsupported Content</string>
|
<string name="unsupported_content">Unsupported Content</string>
|
||||||
<string name="unsupported_content_desc">Sorry, we are unable to display this content in the app. You can find the file named %1$s in your downloads folder.</string>
|
<string name="unsupported_content_desc">Sorry, we are unable to display this content in the app. You can find the file named %1$s in your downloads folder.</string>
|
||||||
|
<string name="nothing_at_this_location">There\'s nothing at this location.</string>
|
||||||
|
<string name="publish_something_here">Publish something here</string>
|
||||||
|
<string name="cannot_view_claim">This content cannot be accessed at this time. Please try again later.</string>
|
||||||
|
<string name="zero_duration">00:00</string>
|
||||||
|
|
||||||
<!-- Channel view -->
|
<!-- Channel view -->
|
||||||
<string name="no_channel_info">There\'s nothing here yet.\nPlease check back later.</string>
|
<string name="no_channel_info">There\'s nothing here yet.\nPlease check back later.</string>
|
||||||
<string name="content">Content</string>
|
<string name="content">Content</string>
|
||||||
<string name="website">Website</string>
|
<string name="website">Website</string>
|
||||||
<string name="reposted">reposted</string>
|
<string name="reposted">reposted</string>
|
||||||
|
<plurals name="follower_count">
|
||||||
|
<item quantity="one">%1$s follower</item>
|
||||||
|
<item quantity="other">%1$s followers</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
<!-- Settings -->
|
<!-- Settings -->
|
||||||
<string name="user_interface">Content & User interface</string>
|
<string name="user_interface">Content & User interface</string>
|
||||||
|
|