diff --git a/app/build.gradle b/app/build.gradle index d80329f993107fc97fb7d85a980a816793b77ee0..7144efd737c9811c7c56501f24d219475591708b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,6 +66,9 @@ dependencies { api 'androidx.annotation:annotation:1.3.0' implementation 'androidx.core:core:1.6.0' implementation 'androidx.appcompat:appcompat:1.0.2' + implementation "androidx.constraintlayout:constraintlayout:2.1.3" + implementation 'com.google.android.material:material:1.5.0' + implementation 'com.github.bumptech.glide:glide:4.13.1' def work_version = "2.7.1" // (Java only) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1400e0b94a5e3c710e9a0e46aaa390a897381bad..b525a98cdb34b7d65767ffd93e7cb110a5410a3a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -21,25 +21,26 @@ - + android:exported="true" + android:label="My Account" + android:theme="@style/AccountActivityTheme" /> + - + aliases; + private OwnCloudClient client; + private Account account; private ActivityAccountsBinding binding; @@ -45,11 +61,29 @@ public class AccountsActivity extends AppCompatActivity { binding = ActivityAccountsBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + setSupportActionBar(binding.toolbar); + + binding.toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onBackPressed(); + } + }); + + binding.settings.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final Intent settingsIntent = buildIntent(Intent.ACTION_VIEW, "") + .setComponent(new ComponentName( + EDriveWidget.ACCOUNT_MANAGER_PACKAGE_NAME, ACCOUNT_SETTINGS)); + startActivity(settingsIntent); + } + }); final AccountManager accountManager = AccountManager.get(this); - final Account account = CommonUtils.getAccount(getString(R.string.eelo_account_type), + account = CommonUtils.getAccount(getString(R.string.eelo_account_type), accountManager); - final OwnCloudClient client = CommonUtils.getOwnCloudClient(account, this); + client = CommonUtils.getOwnCloudClient(account, this); final HandlerThread handlerThread = new HandlerThread("Network Request"); handlerThread.start(); @@ -67,6 +101,12 @@ public class AccountsActivity extends AppCompatActivity { } }; + if (!CommonUtils.haveNetworkConnection(this)) { + handleNoInternetConnection(); + return; + } + + binding.loading.setVisibility(View.VISIBLE); mHandler.post(new Runnable() { @Override public void run() { @@ -79,13 +119,14 @@ public class AccountsActivity extends AppCompatActivity { if (aliasResult.isSuccess() && aliasResult.getData() != null) { aliases = aliasResult.getData(); } - callback.onComplete(); } + callback.onComplete(); } }); } private void onNetworkRequestCompleted() { + binding.loading.setVisibility(View.GONE); if (userInfo.displayName == null) { binding.name.setText(userInfo.alternateDisplayName); } else { @@ -96,24 +137,79 @@ public class AccountsActivity extends AppCompatActivity { final int usedMB = convertIntoMB(userInfo.quota.used); final int totalMB = convertIntoMB(userInfo.quota.total); + binding.progress.setMax(totalMB); + binding.progress.setProgress(usedMB); + binding.progress.setVisibility(View.VISIBLE); + binding.plan.setText(getString(R.string.free_plan, CommonUtils.humanReadableByteCountBin(userInfo.quota.total))); - for (String group : userInfo.groups) { if (group.contains("premium-")) { binding.plan.setText(getString(R.string.premium_plan, group.split("-")[1])); break; } } + binding.myPlan.setVisibility(View.VISIBLE); + binding.plan.setVisibility(View.VISIBLE); binding.status.setText(getString(R.string.progress_status, CommonUtils.humanReadableByteCountBin(userInfo.quota.used), CommonUtils.humanReadableByteCountBin(userInfo.quota.total))); if (aliases != null && !aliases.isEmpty()) { - binding.alias1.setText(getString(R.string.alias_dot) + aliases.get(0)); + binding.alias.setVisibility(View.VISIBLE); + binding.alias1.setText(aliases.get(0).toString()); + binding.aliasDivider.setVisibility(View.VISIBLE); } else { - binding.alias1.setText(getString(R.string.no_alias)); + binding.alias.setVisibility(View.GONE); + binding.alias1Container.setVisibility(View.GONE); } + + binding.alias1Clipboard.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CommonUtils.copyToClipboard(Uri.parse(binding.alias1.getText().toString()), + v.getContext(), v.getContext().getString(R.string.alias)); + } + }); + + binding.upgrade.setVisibility(View.VISIBLE); + binding.upgrade.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final Intent upgradeIntent = buildIntent(Intent.ACTION_VIEW, + String.format(EDriveWidget.WEBPAGE, userInfo.id, + client.getCredentials().getAuthToken(), dataForWeb(userInfo.quota.total))); + startActivity(upgradeIntent); + } + }); + + binding.alias.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (binding.alias1Container.getVisibility() == View.VISIBLE) { + binding.alias1Container.setVisibility(View.GONE); + binding.alias.setCompoundDrawablesWithIntrinsicBounds(null, null, + ContextCompat.getDrawable(v.getContext(), R.drawable.ic_expand_more), null); + } else { + binding.alias1Container.setVisibility(View.VISIBLE); + binding.alias.setCompoundDrawablesWithIntrinsicBounds(null, null, + ContextCompat.getDrawable(v.getContext(), R.drawable.ic_expand_less), null); + } + } + }); + + Glide.with(this) + .load(client.getBaseUri() + NON_OFFICIAL_AVATAR_PATH + + client.getCredentials().getUsername() + "/" + 300) + .error(R.mipmap.ic_eelo_foreground) + .into(binding.avatar); + binding.avatar.setVisibility(View.VISIBLE); + } + + private void handleNoInternetConnection() { + binding.name.setText(account.name); + binding.email.setText(account.type); + binding.avatar.setVisibility(View.VISIBLE); } } diff --git a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java index 2c0af0f8e85b4c27f0da3184bd2a97c6073cdf11..f98d74962b53b61fd8e429ef4b9705e08cf485be 100644 --- a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java +++ b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java @@ -15,6 +15,8 @@ import android.accounts.AccountManager; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.Service; +import android.content.ClipData; +import android.content.ClipboardManager; import android.content.ContentResolver; import android.content.Context; import android.media.MediaScannerConnection; @@ -25,6 +27,7 @@ import android.net.Uri; import android.os.Build; import android.util.Log; import android.webkit.MimeTypeMap; +import android.widget.Toast; import com.owncloud.android.lib.common.OwnCloudBasicCredentials; import com.owncloud.android.lib.common.OwnCloudClient; @@ -380,42 +383,42 @@ public abstract class CommonUtils { for (SyncedFolder folder : syncedFolders) { final OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder( - CreateRemoteFolderWorker.class) - .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) - .setInputData(createDataFromSyncedFolder(folder)) - .addTag(AppConstants.WORK_GENERIC_TAG) - .addTag(AppConstants.WORK_INITIALIZATION_TAG) - .setConstraints(constraints) - .build(); + CreateRemoteFolderWorker.class) + .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) + .setInputData(createDataFromSyncedFolder(folder)) + .addTag(AppConstants.WORK_GENERIC_TAG) + .addTag(AppConstants.WORK_INITIALIZATION_TAG) + .setConstraints(constraints) + .build(); workRequests.add(oneTimeWorkRequest); } final OneTimeWorkRequest firstStartRequest = new OneTimeWorkRequest.Builder(FirstStartWorker.class) - .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) - .addTag(AppConstants.WORK_GENERIC_TAG) - .addTag(AppConstants.WORK_INITIALIZATION_TAG) - .build(); + .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) + .addTag(AppConstants.WORK_GENERIC_TAG) + .addTag(AppConstants.WORK_INITIALIZATION_TAG) + .build(); workManager.beginWith(workRequests) - .then(firstStartRequest) - .enqueue(); + .then(firstStartRequest) + .enqueue(); } private static Data createDataFromSyncedFolder(SyncedFolder folder) { return new Data.Builder() - .putInt(DATA_KEY_ID, folder.getId()) - .putString(DATA_KEY_LIBELLE, folder.getLibelle()) - .putString(DATA_KEY_LOCAL_PATH, folder.getLocalFolder()) - .putString(DATA_KEY_REMOTE_PATH, folder.getRemoteFolder()) - .putString(DATA_KEY_LAST_ETAG, folder.getLastEtag()) - .putLong(DATA_KEY_LAST_MODIFIED, folder.getLastModified()) - .putBoolean(DATA_KEY_SCAN_LOCAL, folder.isScanLocal()) - .putBoolean(DATA_KEY_SCAN_REMOTE, folder.isScanRemote()) - .putBoolean(DATA_KEY_ENABLE, folder.isEnabled()) - .putBoolean(DATA_KEY_MEDIATYPE, folder.isMediaType()) - .build(); + .putInt(DATA_KEY_ID, folder.getId()) + .putString(DATA_KEY_LIBELLE, folder.getLibelle()) + .putString(DATA_KEY_LOCAL_PATH, folder.getLocalFolder()) + .putString(DATA_KEY_REMOTE_PATH, folder.getRemoteFolder()) + .putString(DATA_KEY_LAST_ETAG, folder.getLastEtag()) + .putLong(DATA_KEY_LAST_MODIFIED, folder.getLastModified()) + .putBoolean(DATA_KEY_SCAN_LOCAL, folder.isScanLocal()) + .putBoolean(DATA_KEY_SCAN_REMOTE, folder.isScanRemote()) + .putBoolean(DATA_KEY_ENABLE, folder.isEnabled()) + .putBoolean(DATA_KEY_MEDIATYPE, folder.isMediaType()) + .build(); } public static void createNotificationChannel(Context context){ @@ -431,4 +434,14 @@ public abstract class CommonUtils { notificationManager.createNotificationChannel(channel); } } -} \ No newline at end of file + + public static void copyToClipboard(Uri data, Context context, String label) { + final ClipboardManager clipboard = + (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + final ClipData clip = ClipData.newPlainText(label, String.valueOf(data)); + clipboard.setPrimaryClip(clip); + Toast.makeText(context, context.getString(R.string.copied_to_clipboard, label), + Toast.LENGTH_SHORT).show(); + } + +} diff --git a/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java b/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java index 25daf2ad100d3824ccabf9b3ec7eb71a0801df76..229850c657ac2840e4d30fff0ed500e8361d9c48 100644 --- a/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java +++ b/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java @@ -13,8 +13,6 @@ import android.accounts.AccountManager; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; -import android.content.ClipData; -import android.content.ClipboardManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -44,10 +42,10 @@ import foundation.e.drive.utils.CommonUtils; * Implementation of App Widget functionality. */ public class EDriveWidget extends AppWidgetProvider { - private static final String webpage = + public static final String WEBPAGE = "https://esolutions.shop/ecloud-subscriptions/?username=%s&token=%s¤t-quota=%s&from=nextcloud"; + public static final String ACCOUNT_MANAGER_PACKAGE_NAME = "foundation.e.accountmanager"; private static final String ADD_ACCOUNT_WEBPAGE = "https://e.foundation/e-email-invite/"; - private static final String ACCOUNT_MANAGER_PACKAGE_NAME = "foundation.e.accountmanager"; private static final String GET_ACCOUNT_MANAGER_COMPONENT_NAME = ACCOUNT_MANAGER_PACKAGE_NAME + ".ui.setup.LoginActivity"; private static final String SETUP_ACCOUNT_PROVIDER_TYPE = "setup_account_provider_type"; @@ -67,6 +65,26 @@ public class EDriveWidget extends AppWidgetProvider { private UserInfo userInfo = null; private RemoteViews views = null; + public static String dataForWeb(Long bytes) { + final String space = CommonUtils.humanReadableByteCountBin(bytes); + final String[] split = space.split(" "); + return Math.round(Double.parseDouble(split[0])) + split[1]; + } + + public static Intent buildIntent(String name, String extra) { + final Intent intent = new Intent(name); + if (!extra.isEmpty()) { + intent.setData(Uri.parse(extra)); + } + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + return intent; + } + + public static int convertIntoMB(Long quota) { + return (int) (quota / 1048576); // 1024.0 * 1024.0 = 1048576.0 + } + public void updateAppWidget(final Context context) { AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); final ComponentName provider = new ComponentName(context, getClass()); @@ -152,28 +170,13 @@ public class EDriveWidget extends AppWidgetProvider { updateAppWidget(context); break; case COPY_ALIAS: - copyToClipboard(intent.getData(), context); + CommonUtils.copyToClipboard(intent.getData(), context, + context.getString(R.string.alias)); break; } super.onReceive(context, intent); } - private String dataForWeb(Long bytes) { - final String space = CommonUtils.humanReadableByteCountBin(bytes); - final String[] split = space.split(" "); - return Math.round(Double.parseDouble(split[0])) + split[1]; - } - - private Intent buildIntent(String name, String extra) { - final Intent intent = new Intent(name); - if (!extra.isEmpty()) { - intent.setData(Uri.parse(extra)); - } - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - return intent; - } - private void onNetworkRequestCompleted(Context context, AppWidgetManager appWidgetManager, int appWidgetId, OwnCloudClient client, Account account) { if (account == null || userInfo == null) { @@ -250,7 +253,7 @@ public class EDriveWidget extends AppWidgetProvider { views.setOnClickPendingIntent(R.id.settings, pendingIntentSettings); final PendingIntent pendingIntentUpgrade = PendingIntent.getActivity(context, 0, - buildIntent(Intent.ACTION_VIEW, String.format(webpage, userInfo.id, + buildIntent(Intent.ACTION_VIEW, String.format(WEBPAGE, userInfo.id, client.getCredentials().getAuthToken(), dataForWeb(userInfo.quota.total))), PendingIntent.FLAG_IMMUTABLE); views.setOnClickPendingIntent(R.id.upgrade, pendingIntentUpgrade); @@ -268,14 +271,4 @@ public class EDriveWidget extends AppWidgetProvider { return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE); } - private void copyToClipboard(Uri data, Context context) { - final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - final ClipData clip = ClipData.newPlainText("alias", String.valueOf(data)); - clipboard.setPrimaryClip(clip); - } - - public static int convertIntoMB(Long quota) { - return (int) (quota / 1048576); // 1024.0 * 1024.0 = 1048576.0 - } - } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_back.xml b/app/src/main/res/drawable/ic_arrow_back.xml new file mode 100644 index 0000000000000000000000000000000000000000..6c6a4b746bad7bbbca8ccc7e3c235d3da4c48229 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_back.xml @@ -0,0 +1,23 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_expand_less.xml b/app/src/main/res/drawable/ic_expand_less.xml new file mode 100644 index 0000000000000000000000000000000000000000..fd974a0cb54260b2d3b8c16c570bbcc88c22328d --- /dev/null +++ b/app/src/main/res/drawable/ic_expand_less.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_expand_more.xml b/app/src/main/res/drawable/ic_expand_more.xml new file mode 100644 index 0000000000000000000000000000000000000000..6f347250df8b0107a25e459ed21cb94407a8d7e0 --- /dev/null +++ b/app/src/main/res/drawable/ic_expand_more.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_accounts.xml b/app/src/main/res/layout/activity_accounts.xml index c12bcf3adf42f1b3602893a3bafc765b2f210802..2cf82845d34d113863b781b4da8544a7c150969d 100644 --- a/app/src/main/res/layout/activity_accounts.xml +++ b/app/src/main/res/layout/activity_accounts.xml @@ -1,39 +1,254 @@ - - + - + - + - + + + + + + + + + + + + + - + + + + android:layout_height="wrap_content" + android:layout_marginHorizontal="15dp" + android:layout_marginTop="20dp" + android:drawableEnd="@drawable/ic_expand_more" + android:drawablePadding="10dp" + android:text="@string/aliases" + android:textColor="@color/textColorPrimary" + android:textFontWeight="400" + android:textSize="16sp" + android:textStyle="bold" + android:visibility="gone" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/header" /> + + + + + + + -