Compare commits
14 commits
Author | SHA1 | Date | |
---|---|---|---|
|
fdd759b241 | ||
|
57cd649c02 | ||
|
7250435d7f | ||
|
b81abf74a1 | ||
|
208e2c2d42 | ||
|
a5bdd1c042 | ||
|
1e3a74cae1 | ||
|
ca08f71a72 | ||
|
b60ca39df1 | ||
|
696bc86b7c | ||
|
4c163c6244 | ||
|
2ad49ca281 | ||
|
56caeef72b | ||
|
84bb014557 |
26 changed files with 166 additions and 51 deletions
1
.github/workflows/deploy.yml
vendored
Normal file
1
.github/workflows/deploy.yml
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
|
|
@ -28,6 +28,8 @@ twitterConsumerKey=XXXXXX
|
|||
twitterConsumerSecret=XXXXXX
|
||||
```
|
||||
|
||||
Copy the file 'google-services.sample.json' to 'google-services.json' in the app/ folder.
|
||||
|
||||
Click the Sync button and when process finishes, the Run button to launch the app on your simulator or connected debugging device after the build process is complete.
|
||||
|
||||
## Contributing
|
||||
|
@ -37,7 +39,7 @@ Contributions to this project are welcome, encouraged, and compensated. For more
|
|||
This project is MIT licensed. For the full license, see [LICENSE](LICENSE).
|
||||
|
||||
## Security
|
||||
We take security seriously. Please contact security@lbry.com regarding any security issues. Our PGP key is [here](https://keybase.io/lbry/key.asc) if you need it.
|
||||
We take security seriously. Please contact security@lbry.com regarding any security issues. Our PGP key is [here](https://lbry.com/faq/pgp-key) if you need it.
|
||||
|
||||
## Contact
|
||||
The primary contact for this project is [@akinwale](https://github.com/akinwale) (akinwale@lbry.com)
|
||||
|
|
|
@ -21,7 +21,7 @@ android {
|
|||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
packagingOptions {
|
||||
exclude 'META-INF/DEPENDENCIES'
|
||||
exclude 'lib/x86_64/darwin/libscrypt.dylib'
|
||||
}
|
||||
|
@ -122,6 +122,9 @@ dependencies {
|
|||
implementation 'org.bitcoinj:bitcoinj-tools:0.14.7'
|
||||
implementation 'org.java-websocket:Java-WebSocket:1.5.1'
|
||||
|
||||
implementation ('com.journeyapps:zxing-android-embedded:4.1.0') { transitive = false }
|
||||
implementation 'com.google.zxing:core:3.3.0'
|
||||
|
||||
compileOnly 'org.projectlombok:lombok:1.18.10'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.10'
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
|
||||
|
@ -132,8 +135,8 @@ dependencies {
|
|||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
|
||||
__32bitImplementation 'io.lbry:lbrysdk32:0.100.0'
|
||||
__64bitImplementation 'io.lbry:lbrysdk64:0.100.0'
|
||||
__32bitImplementation 'io.lbry:lbrysdk32:0.102.0'
|
||||
__64bitImplementation 'io.lbry:lbrysdk64:0.102.0'
|
||||
//__64bitImplementation(name: 'lbrysdk', ext: 'aar')
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="io.lbry.browser"
|
||||
android:installLocation="auto">
|
||||
|
||||
|
@ -13,6 +14,8 @@
|
|||
<uses-permission android:name="com.android.vending.BILLING" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
|
||||
<uses-sdk tools:overrideLibrary="com.google.zxing.client.android" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
@ -98,6 +101,11 @@
|
|||
android:theme="@style/AppTheme.NoActionBarTranslucent"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<activity
|
||||
android:name="com.journeyapps.barcodescanner.CaptureActivity"
|
||||
android:screenOrientation="fullSensor"
|
||||
tools:replace="screenOrientation" />
|
||||
|
||||
<service
|
||||
android:name="io.lbry.browser.LbrynetMessagingService"
|
||||
android:exported="false">
|
||||
|
|
|
@ -2102,7 +2102,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
if (nowPlayingClaimBitmap == null &&
|
||||
nowPlayingClaim != null &&
|
||||
!Helper.isNullOrEmpty(nowPlayingClaim.getThumbnailUrl())) {
|
||||
Glide.with(getApplicationContext()).asBitmap().load(nowPlayingClaim.getThumbnailUrl()).into(new CustomTarget<Bitmap>() {
|
||||
Glide.with(getApplicationContext()).asBitmap().load(nowPlayingClaim.getThumbnailUrl(0, 0, 75)).into(new CustomTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
nowPlayingClaimBitmap = resource;
|
||||
|
|
|
@ -95,7 +95,7 @@ public class ChannelFilterListAdapter extends RecyclerView.Adapter<ChannelFilter
|
|||
vh.allView.setVisibility(claim.isPlaceholder() ? View.VISIBLE : View.GONE);
|
||||
|
||||
vh.titleView.setText(Helper.isNullOrEmpty(claim.getTitle()) ? claim.getName() : claim.getTitle());
|
||||
String thumbnailUrl = claim.getThumbnailUrl();
|
||||
String thumbnailUrl = claim.getThumbnailUrl(vh.thumbnailView.getLayoutParams().width, vh.thumbnailView.getLayoutParams().height, 85);
|
||||
if (!Helper.isNullOrEmpty(thumbnailUrl) && context != null) {
|
||||
Glide.with(context.getApplicationContext()).load(thumbnailUrl).apply(RequestOptions.circleCropTransform()).into(vh.thumbnailView);
|
||||
}
|
||||
|
|
|
@ -334,7 +334,8 @@ public class ClaimListAdapter extends RecyclerView.Adapter<ClaimListAdapter.View
|
|||
if (metadata instanceof Claim.StreamMetadata) {
|
||||
streamMetadata = (Claim.StreamMetadata) metadata;
|
||||
}
|
||||
String thumbnailUrl = item.getThumbnailUrl();
|
||||
|
||||
String thumbnailUrl = item.getThumbnailUrl(vh.thumbnailView.getLayoutParams().width, vh.thumbnailView.getLayoutParams().height, 85);
|
||||
long publishTime = (streamMetadata != null && streamMetadata.getReleaseTime() > 0) ? streamMetadata.getReleaseTime() * 1000 : item.getTimestamp() * 1000;
|
||||
int bgColor = Helper.generateRandomColorForValue(item.getClaimId());
|
||||
if (bgColor == 0) {
|
||||
|
|
|
@ -190,7 +190,7 @@ public class CommentListAdapter extends RecyclerView.Adapter<CommentListAdapter.
|
|||
int bgColor = Helper.generateRandomColorForValue(comment.getChannelId());
|
||||
Helper.setIconViewBackgroundColor(holder.noThumbnailView, bgColor, false, context);
|
||||
if (hasThumbnail) {
|
||||
Glide.with(context.getApplicationContext()).asBitmap().load(comment.getPoster().getThumbnailUrl()).
|
||||
Glide.with(context.getApplicationContext()).asBitmap().load(comment.getPoster().getThumbnailUrl(holder.thumbnailView.getLayoutParams().width, holder.thumbnailView.getLayoutParams().height, 85)).
|
||||
apply(RequestOptions.circleCropTransform()).into(holder.thumbnailView);
|
||||
}
|
||||
holder.alphaView.setText(comment.getChannelName() != null ? comment.getChannelName().substring(1, 2).toUpperCase() : null);
|
||||
|
|
|
@ -193,7 +193,7 @@ public class NotificationListAdapter extends RecyclerView.Adapter<NotificationLi
|
|||
vh.thumbnailView.setVisibility(notification.getCommentAuthor() == null ? View.INVISIBLE : View.VISIBLE);
|
||||
if (notification.getCommentAuthor() != null) {
|
||||
Glide.with(context.getApplicationContext()).load(
|
||||
notification.getCommentAuthor().getThumbnailUrl()).apply(RequestOptions.circleCropTransform()).into(vh.thumbnailView);
|
||||
notification.getCommentAuthor().getThumbnailUrl(vh.thumbnailView.getLayoutParams().width, vh.thumbnailView.getLayoutParams().height, 85)).apply(RequestOptions.circleCropTransform()).into(vh.thumbnailView);
|
||||
}
|
||||
|
||||
vh.iconView.setVisibility(notification.getCommentAuthor() != null ? View.INVISIBLE : View.VISIBLE);
|
||||
|
|
|
@ -89,7 +89,8 @@ public class SuggestedChannelGridAdapter extends RecyclerView.Adapter<SuggestedC
|
|||
@Override
|
||||
public void onBindViewHolder(SuggestedChannelGridAdapter.ViewHolder vh, int position) {
|
||||
Claim claim = items.get(position);
|
||||
String thumbnailUrl = claim.getThumbnailUrl();
|
||||
ViewGroup.LayoutParams lp = vh.thumbnailView.getLayoutParams();
|
||||
String thumbnailUrl = claim.getThumbnailUrl(lp.width, lp.height, 85);
|
||||
|
||||
int bgColor = Helper.generateRandomColorForValue(claim.getClaimId());
|
||||
Helper.setIconViewBackgroundColor(vh.noThumbnailView, bgColor, false, context);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package io.lbry.browser.model;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
@ -184,6 +186,21 @@ public class Claim {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URL from the CDN where getting the image file
|
||||
* @param width Pass zero for width and height for the full size image file
|
||||
* @param height Pass zero for width and height for the full size image file
|
||||
* @param q Desired quality for the image to be retrieved
|
||||
* @return URL from the CDN from where image can be retrieved
|
||||
*/
|
||||
public String getThumbnailUrl(int width, int height, int q) {
|
||||
if (value != null && value.getThumbnail() != null) {
|
||||
ImageCDNUrl imageCDNUrl = new ImageCDNUrl(Math.max(width, 0), Math.max(height, 0), q, null, value.getThumbnail().getUrl());
|
||||
return imageCDNUrl.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getCoverUrl() {
|
||||
if (TYPE_CHANNEL.equals(valueType) && value != null && value instanceof ChannelMetadata && ((ChannelMetadata) value).getCover() != null) {
|
||||
return ((ChannelMetadata) value).getCover().getUrl();
|
||||
|
@ -491,6 +508,30 @@ public class Claim {
|
|||
private String url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Object to be instantiated. In order to get the URLto the CDN, call toString() on it
|
||||
*/
|
||||
static class ImageCDNUrl {
|
||||
private String appendedPath = "";
|
||||
|
||||
public ImageCDNUrl(int width, int height, int quality, @Nullable String format, String thumbnailUrl) {
|
||||
if (width != 0 && height != 0)
|
||||
appendedPath = "s:".concat(String.valueOf(width)).concat(":").concat(String.valueOf(height)).concat("/");
|
||||
|
||||
appendedPath = appendedPath.concat("quality:").concat(String.valueOf(quality)).concat("/");
|
||||
|
||||
appendedPath = appendedPath.concat("plain/").concat(thumbnailUrl);
|
||||
|
||||
if (format != null)
|
||||
appendedPath = appendedPath.concat("@").concat(format);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String url = "https://image-processor.vanwanet.com/optimize/";
|
||||
return url.concat(appendedPath);
|
||||
}
|
||||
}
|
||||
@Data
|
||||
public static class StreamInfo {
|
||||
private long duration; // video / audio
|
||||
|
|
|
@ -467,7 +467,7 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen
|
|||
if (hasThumbnail && context != null) {
|
||||
Glide.with(context.getApplicationContext()).
|
||||
asBitmap().
|
||||
load(channel.getThumbnailUrl()).
|
||||
load(channel.getThumbnailUrl(commentPostAsThumbnail.getLayoutParams().width, commentPostAsThumbnail.getLayoutParams().height, 85)).
|
||||
apply(RequestOptions.circleCropTransform()).
|
||||
into(commentPostAsThumbnail);
|
||||
}
|
||||
|
|
|
@ -285,7 +285,7 @@ public class ChannelFormFragment extends BaseFragment implements
|
|||
coverUrl = currentClaim.getCoverUrl();
|
||||
}
|
||||
if (!Helper.isNullOrEmpty(currentClaim.getThumbnailUrl())) {
|
||||
Glide.with(context.getApplicationContext()).load(currentClaim.getThumbnailUrl()).apply(RequestOptions.circleCropTransform()).into(imageThumbnail);
|
||||
Glide.with(context.getApplicationContext()).load(currentClaim.getThumbnailUrl(imageThumbnail.getLayoutParams().width, imageThumbnail.getLayoutParams().height, 85)).apply(RequestOptions.circleCropTransform()).into(imageThumbnail);
|
||||
thumbnailUrl = currentClaim.getThumbnailUrl();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -538,11 +538,15 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
|
|||
else
|
||||
buttonTip.setVisibility(View.VISIBLE);
|
||||
|
||||
String thumbnailUrl = claim.getThumbnailUrl();
|
||||
String thumbnailUrl = "";
|
||||
String coverUrl = claim.getCoverUrl();
|
||||
textTitle.setText(Helper.isNullOrEmpty(claim.getTitle()) ? claim.getName() : claim.getTitle());
|
||||
|
||||
Context context = getContext();
|
||||
|
||||
if (context != null) {
|
||||
thumbnailUrl = claim.getThumbnailUrl(imageThumbnail.getLayoutParams().width, imageThumbnail.getLayoutParams().height, 85);
|
||||
}
|
||||
if (context != null && !Helper.isNullOrEmpty(coverUrl)) {
|
||||
Glide.with(context.getApplicationContext()).load(coverUrl).centerCrop().into(imageCover);
|
||||
}
|
||||
|
|
|
@ -316,7 +316,10 @@ public class FileViewFragment extends BaseFragment implements
|
|||
hideBuffering();
|
||||
|
||||
if (loadingNewClaim) {
|
||||
MainActivity.appPlayer.setPlayWhenReady(Objects.requireNonNull((MainActivity) (getActivity())).isMediaAutoplayEnabled());
|
||||
Context context = getContext();
|
||||
if (context instanceof MainActivity) {
|
||||
MainActivity.appPlayer.setPlayWhenReady(((MainActivity) context).isMediaAutoplayEnabled());
|
||||
}
|
||||
loadingNewClaim = false;
|
||||
}
|
||||
} else if (playbackState == Player.STATE_BUFFERING) {
|
||||
|
@ -1566,7 +1569,8 @@ public class FileViewFragment extends BaseFragment implements
|
|||
int bgColor = Helper.generateRandomColorForValue(signingChannel.getClaimId());
|
||||
Helper.setIconViewBackgroundColor(root.findViewById(R.id.file_view_publisher_no_thumbnail), bgColor, false, context);
|
||||
if (hasPublisherThumbnail && context != null) {
|
||||
Glide.with(context.getApplicationContext()).load(signingChannel.getThumbnailUrl()).
|
||||
ViewGroup.LayoutParams lp = root.findViewById(R.id.file_view_publisher_thumbnail).getLayoutParams();
|
||||
Glide.with(context.getApplicationContext()).load(signingChannel.getThumbnailUrl(lp.width, lp.height, 85)).
|
||||
apply(RequestOptions.circleCropTransform()).into((ImageView) root.findViewById(R.id.file_view_publisher_thumbnail));
|
||||
}
|
||||
((TextView) root.findViewById(R.id.file_view_publisher_thumbnail_alpha)).
|
||||
|
@ -1606,7 +1610,7 @@ public class FileViewFragment extends BaseFragment implements
|
|||
Claim.GenericMetadata metadata = claim.getValue();
|
||||
if (!Helper.isNullOrEmpty(claim.getThumbnailUrl())) {
|
||||
ImageView thumbnailView = root.findViewById(R.id.file_view_thumbnail);
|
||||
Glide.with(context.getApplicationContext()).asBitmap().load(claim.getThumbnailUrl()).centerCrop().into(thumbnailView);
|
||||
Glide.with(context.getApplicationContext()).asBitmap().load(claim.getThumbnailUrl(context.getResources().getDisplayMetrics().widthPixels, thumbnailView.getLayoutParams().height, 85)).centerCrop().into(thumbnailView);
|
||||
} else {
|
||||
// display first x letters of claim name, with random background
|
||||
}
|
||||
|
@ -3243,7 +3247,7 @@ public class FileViewFragment extends BaseFragment implements
|
|||
if (hasThumbnail && context != null) {
|
||||
Glide.with(context.getApplicationContext()).
|
||||
asBitmap().
|
||||
load(channel.getThumbnailUrl()).
|
||||
load(channel.getThumbnailUrl(commentPostAsThumbnail.getLayoutParams().width, commentPostAsThumbnail.getLayoutParams().height, 85)).
|
||||
apply(RequestOptions.circleCropTransform()).
|
||||
into(commentPostAsThumbnail);
|
||||
}
|
||||
|
|
|
@ -583,7 +583,9 @@ public class PublishFormFragment extends BaseFragment implements
|
|||
Context context = getContext();
|
||||
try {
|
||||
Claim.StreamMetadata metadata = (Claim.StreamMetadata) currentClaim.getValue();
|
||||
uploadedThumbnailUrl = currentClaim.getThumbnailUrl();
|
||||
if (context != null) {
|
||||
uploadedThumbnailUrl = currentClaim.getThumbnailUrl(imageThumbnail.getLayoutParams().width, imageThumbnail.getLayoutParams().height, 85);
|
||||
}
|
||||
if (context != null && !Helper.isNullOrEmpty(uploadedThumbnailUrl)) {
|
||||
Glide.with(context.getApplicationContext()).load(uploadedThumbnailUrl).centerCrop().into(imageThumbnail);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.lbry.browser.ui.wallet;
|
|||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
|
@ -60,6 +61,9 @@ import java.util.concurrent.Future;
|
|||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
import io.lbry.browser.MainActivity;
|
||||
import io.lbry.browser.R;
|
||||
import io.lbry.browser.adapter.TransactionListAdapter;
|
||||
|
@ -117,6 +121,7 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
|
|||
private ImageButton buttonCopyReceiveAddress;
|
||||
private MaterialButton buttonGetNewAddress;
|
||||
private TextInputEditText inputSendAddress;
|
||||
private ImageButton buttonQRScanAddress;
|
||||
private TextInputEditText inputSendAmount;
|
||||
private MaterialButton buttonSend;
|
||||
private TextView textConnectedEmail;
|
||||
|
@ -162,6 +167,7 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
|
|||
buttonCopyReceiveAddress = root.findViewById(R.id.wallet_copy_receive_address);
|
||||
buttonGetNewAddress = root.findViewById(R.id.wallet_get_new_address);
|
||||
inputSendAddress = root.findViewById(R.id.wallet_input_send_address);
|
||||
buttonQRScanAddress = root.findViewById(R.id.wallet_qr_scan_address);
|
||||
inputSendAmount = root.findViewById(R.id.wallet_input_amount);
|
||||
buttonSend = root.findViewById(R.id.wallet_send);
|
||||
textConnectedEmail = root.findViewById(R.id.wallet_connected_email);
|
||||
|
@ -368,6 +374,13 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
|
|||
copyReceiveAddress();
|
||||
}
|
||||
});
|
||||
buttonQRScanAddress.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
IntentIntegrator intentIntegrator = IntentIntegrator.forSupportFragment(WalletFragment.this);
|
||||
intentIntegrator.setOrientationLocked(false).initiateScan();
|
||||
}
|
||||
});
|
||||
buttonSend.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
@ -800,4 +813,12 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
|
|||
checkRewardsDriverCard(rewardsDriverText, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == IntentIntegrator.REQUEST_CODE) {
|
||||
IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
|
||||
String code = intentResult.getContents();
|
||||
inputSendAddress.setText(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public final class Lbry {
|
|||
|
||||
public static final int TTL_CLAIM_SEARCH_VALUE = 120000; // 2-minute TTL for cache
|
||||
public static final String SDK_CONNECTION_STRING = "http://127.0.0.1:5279";
|
||||
public static final String LBRY_TV_CONNECTION_STRING = "https://api.lbry.tv/api/v1/proxy";
|
||||
public static final String LBRY_TV_CONNECTION_STRING = "https://api.na-backend.odysee.com/api/v1/proxy";
|
||||
public static final String TAG = "Lbry";
|
||||
|
||||
// Values to obtain from LBRY SDK status
|
||||
|
|
|
@ -141,20 +141,6 @@ public class LbryUri {
|
|||
boolean isChannel = includesChannel && Helper.isNullOrEmpty(possibleStreamName);
|
||||
String channelName = includesChannel && streamOrChannelName.length() > 1 ? streamOrChannelName.substring(1) : null;
|
||||
|
||||
/*
|
||||
* It would have thrown already on the RegEx parser if protocol value was incorrect
|
||||
* or HTTPS host was unknown to us.
|
||||
*
|
||||
* [https://] hosts use ':' as ModSeparators while [lbry://] protocol expects '#'
|
||||
*/
|
||||
|
||||
if (!components.get(1).isEmpty()) {
|
||||
if (primaryModSeparator.equals(":"))
|
||||
primaryModSeparator = "#";
|
||||
if (secondaryModSeparator.equals(":"))
|
||||
secondaryModSeparator = "#";
|
||||
}
|
||||
|
||||
if (includesChannel) {
|
||||
if (Helper.isNullOrEmpty(channelName)) {
|
||||
throw new LbryUriException("No channel name after @.");
|
||||
|
@ -329,9 +315,9 @@ public class LbryUri {
|
|||
throw new LbryUriException(String.format("No modifier provided after separator %s", modSeparator));
|
||||
}
|
||||
|
||||
if ("#".equals(modSeparator)) {
|
||||
if ("#".equals(modSeparator) || ":".equals(modSeparator)) {
|
||||
claimId = modValue;
|
||||
} else if (":".equals(modSeparator)) {
|
||||
} else if ("*".equals(modSeparator)) {
|
||||
claimSequence = Helper.parseInt(modValue, -1);
|
||||
} else if ("$".equals(modSeparator)) {
|
||||
bidPosition = Helper.parseInt(modValue, -1);
|
||||
|
|
10
app/src/main/res/drawable-anydpi/ic_qr_scanner.xml
Executable file
10
app/src/main/res/drawable-anydpi/ic_qr_scanner.xml
Executable file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M9.5,6.5v3h-3v-3H9.5M11,5H5v6h6V5L11,5zM9.5,14.5v3h-3v-3H9.5M11,13H5v6h6V13L11,13zM17.5,6.5v3h-3v-3H17.5M19,5h-6v6h6V5L19,5zM13,13h1.5v1.5H13V13zM14.5,14.5H16V16h-1.5V14.5zM16,13h1.5v1.5H16V13zM13,16h1.5v1.5H13V16zM14.5,17.5H16V19h-1.5V17.5zM16,16h1.5v1.5H16V16zM17.5,14.5H19V16h-1.5V14.5zM17.5,17.5H19V19h-1.5V17.5zM22,7h-2V4h-3V2h5V7zM22,22v-5h-2v3h-3v2H22zM2,22h5v-2H4v-3H2V22zM2,2v5h2V4h3V2H2z"/>
|
||||
</vector>
|
BIN
app/src/main/res/drawable-hdpi/ic_qr_scanner.png
Executable file
BIN
app/src/main/res/drawable-hdpi/ic_qr_scanner.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 217 B |
BIN
app/src/main/res/drawable-mdpi/ic_qr_scanner.png
Executable file
BIN
app/src/main/res/drawable-mdpi/ic_qr_scanner.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 145 B |
BIN
app/src/main/res/drawable-xhdpi/ic_qr_scanner.png
Executable file
BIN
app/src/main/res/drawable-xhdpi/ic_qr_scanner.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 159 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_qr_scanner.png
Executable file
BIN
app/src/main/res/drawable-xxhdpi/ic_qr_scanner.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 176 B |
|
@ -19,18 +19,41 @@
|
|||
android:text="@string/send_credits"
|
||||
android:textSize="20sp"/>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/recipient_address">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/wallet_input_send_address"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="14sp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:imeOptions="actionNext" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/recipient_address"
|
||||
android:layout_toStartOf="@id/wallet_qr_scan_address">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/wallet_input_send_address"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:imeOptions="actionNext"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/wallet_qr_scan_address"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="@null"
|
||||
android:src="@drawable/ic_qr_scanner"
|
||||
android:tint="@color/lbryGreen" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_marginTop="16dp"
|
||||
|
|
|
@ -10,6 +10,7 @@ import static org.junit.Assert.assertEquals;
|
|||
|
||||
public class LbryUriTest {
|
||||
private LbryUri expected;
|
||||
private LbryUri expectedOctoshape;
|
||||
|
||||
/*
|
||||
* Create an LbryUri object and assign fields manually using class methods. This object will be
|
||||
|
@ -18,14 +19,21 @@ public class LbryUriTest {
|
|||
@Before
|
||||
public void createExpected() {
|
||||
expected = new LbryUri();
|
||||
expectedOctoshape = new LbryUri();
|
||||
expected.setChannelName("@lbry");
|
||||
expected.setStreamName("lbryturns4");
|
||||
expectedOctoshape.setChannelName("@lbry");
|
||||
expectedOctoshape.setStreamName("lbryturns4");
|
||||
|
||||
try {
|
||||
LbryUri.UriModifier primaryMod = LbryUri.UriModifier.parse("#", "3f");
|
||||
LbryUri.UriModifier secondaryMod = LbryUri.UriModifier.parse("#", "6");
|
||||
LbryUri.UriModifier primaryMod = LbryUri.UriModifier.parse(":", "3f");
|
||||
LbryUri.UriModifier secondaryMod = LbryUri.UriModifier.parse(":", "6");
|
||||
LbryUri.UriModifier primaryModOctoshape = LbryUri.UriModifier.parse("#", "3f");
|
||||
LbryUri.UriModifier secondaryModOctoshape = LbryUri.UriModifier.parse("#", "6");
|
||||
expected.setChannelClaimId(primaryMod.getClaimId());
|
||||
expected.setStreamClaimId(secondaryMod.getClaimId());
|
||||
expectedOctoshape.setChannelClaimId(primaryModOctoshape.getClaimId());
|
||||
expectedOctoshape.setStreamClaimId(secondaryModOctoshape.getClaimId());
|
||||
} catch (LbryUriException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -71,7 +79,7 @@ public class LbryUriTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void parseLbryProtocolWithChannel() {
|
||||
public void parseLbryProtocolWithChannelOctoshape() {
|
||||
LbryUri obtained = new LbryUri();
|
||||
|
||||
try {
|
||||
|
@ -80,12 +88,12 @@ public class LbryUriTest {
|
|||
e.printStackTrace();
|
||||
}
|
||||
|
||||
assertEquals(expected, obtained);
|
||||
assertEquals(expectedOctoshape, obtained);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseLbryProtocolOnlyChannel() {
|
||||
LbryUri expectedForChannel = sinthesizeExpected();
|
||||
LbryUri expectedForChannel = sinthesizeExpectedChannelOctoshape();
|
||||
|
||||
LbryUri obtained = new LbryUri();
|
||||
|
||||
|
@ -100,7 +108,7 @@ public class LbryUriTest {
|
|||
|
||||
@Test
|
||||
public void parseLbryTvProtocolOnlyChannel() {
|
||||
LbryUri expectedForChannel = sinthesizeExpected();
|
||||
LbryUri expectedForChannel = sinthesizeExpectedChannelOctoshape();
|
||||
|
||||
LbryUri obtained = new LbryUri();
|
||||
|
||||
|
@ -192,7 +200,7 @@ public class LbryUriTest {
|
|||
}
|
||||
|
||||
@NotNull
|
||||
private LbryUri sinthesizeExpected() {
|
||||
private LbryUri sinthesizeExpectedChannelOctoshape() {
|
||||
LbryUri expectedForChannel = new LbryUri();
|
||||
expectedForChannel.setChannelName("@UCBerkeley");
|
||||
expectedForChannel.setChannel(true);
|
||||
|
|
Loading…
Reference in a new issue