mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Added pending uploads screen
This commit is contained in:
parent
9a2a56c1cf
commit
13b4987a54
30 changed files with 1329 additions and 514 deletions
|
|
@ -1,262 +1,247 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
|
||||
<uses-permission android:name="android.permission.REORDER_TASKS" />
|
||||
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
|
||||
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
|
||||
<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS" />
|
||||
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<queries>
|
||||
<!-- Browser -->
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="https" />
|
||||
</intent>
|
||||
<!-- Google Maps -->
|
||||
<package android:name="com.google.android.apps.maps" />
|
||||
</queries>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
|
||||
<uses-permission android:name="android.permission.REORDER_TASKS" />
|
||||
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
|
||||
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS" />
|
||||
<uses-permission android:name="android.permission.SET_WALLPAPER" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
|
||||
|
||||
<queries>
|
||||
|
||||
<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
|
||||
<uses-feature android:name="android.hardware.location.gps" />
|
||||
<!-- Browser -->
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<application
|
||||
android:name=".CommonsApplication"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/LightAppTheme"
|
||||
android:largeHeap="true"
|
||||
android:supportsRtl="true"
|
||||
tools:replace="android:appComponentFactory"
|
||||
android:appComponentFactory="commons"
|
||||
android:requestLegacyExternalStorage = "true"
|
||||
tools:ignore="GoogleAppIndexingWarning">
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<activity
|
||||
android:theme="@style/EditActivityTheme"
|
||||
android:name=".description.DescriptionEditActivity"
|
||||
android:exported="true" />
|
||||
<data android:scheme="https" />
|
||||
</intent>
|
||||
<!-- Google Maps -->
|
||||
<package android:name="com.google.android.apps.maps" />
|
||||
</queries> <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
|
||||
<uses-feature android:name="android.hardware.location.gps" />
|
||||
|
||||
<activity
|
||||
android:name=".edit.EditActivity"
|
||||
android:exported="false" />
|
||||
<application
|
||||
android:name=".CommonsApplication"
|
||||
android:appComponentFactory="commons"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/LightAppTheme"
|
||||
tools:ignore="GoogleAppIndexingWarning"
|
||||
tools:replace="android:appComponentFactory">
|
||||
<activity
|
||||
android:name=".upload.UploadProgressActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".description.DescriptionEditActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/EditActivityTheme" />
|
||||
<activity
|
||||
android:name=".edit.EditActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name="org.acra.dialog.CrashReportDialog"
|
||||
android:excludeFromRecents="true"
|
||||
android:finishOnTaskLaunch="true"
|
||||
android:launchMode="singleInstance"
|
||||
android:process=":acra" />
|
||||
<activity
|
||||
android:name=".media.ZoomableActivity"
|
||||
android:configChanges="screenSize|keyboard|orientation"
|
||||
android:label="Zoomable Activity"
|
||||
android:parentActivityName=".customselector.ui.selector.CustomSelectorActivity" />
|
||||
<activity
|
||||
android:name=".auth.LoginActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
||||
<activity android:name="org.acra.dialog.CrashReportDialog"
|
||||
android:process=":acra"
|
||||
android:launchMode="singleInstance"
|
||||
android:excludeFromRecents="true"
|
||||
android:finishOnTaskLaunch="true" />
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
|
||||
<activity
|
||||
android:name=".media.ZoomableActivity"
|
||||
android:label="Zoomable Activity"
|
||||
android:configChanges="screenSize|keyboard|orientation"
|
||||
android:parentActivityName=".customselector.ui.selector.CustomSelectorActivity" />
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
<activity android:name=".WelcomeActivity" />
|
||||
<activity
|
||||
android:name=".upload.UploadActivity"
|
||||
android:configChanges="orientation|screenSize|keyboard"
|
||||
android:exported="true"
|
||||
android:hardwareAccelerated="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter android:label="@string/intent_share_upload_label">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
|
||||
<activity android:name=".auth.LoginActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="audio/ogg" />
|
||||
</intent-filter>
|
||||
<intent-filter android:label="@string/intent_share_upload_label">
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
|
||||
<meta-data android:name="android.app.shortcuts"
|
||||
android:resource="@xml/shortcuts" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
</activity>
|
||||
<activity android:name=".WelcomeActivity" />
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="audio/ogg" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".contributions.MainActivity"
|
||||
android:configChanges="screenSize|keyboard|orientation"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name" />
|
||||
<activity
|
||||
android:name=".settings.SettingsActivity"
|
||||
android:label="@string/title_activity_settings" />
|
||||
<activity
|
||||
android:name=".AboutActivity"
|
||||
android:label="@string/title_activity_about"
|
||||
android:parentActivityName=".contributions.MainActivity" />
|
||||
<activity
|
||||
android:name=".auth.SignupActivity"
|
||||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/title_activity_signup" />
|
||||
<activity
|
||||
android:name=".notification.NotificationActivity"
|
||||
android:label="@string/navigation_item_notification" />
|
||||
<activity
|
||||
android:name=".quiz.QuizActivity"
|
||||
android:label="@string/quiz" />
|
||||
<activity
|
||||
android:name=".quiz.QuizResultActivity"
|
||||
android:label="@string/result" />
|
||||
<activity
|
||||
android:name=".customselector.ui.selector.CustomSelectorActivity"
|
||||
android:configChanges="screenSize|keyboard|orientation"
|
||||
android:label="@string/title_activity_custom_selector"
|
||||
android:parentActivityName=".contributions.MainActivity" />
|
||||
<activity
|
||||
android:name=".category.CategoryDetailsActivity"
|
||||
android:configChanges="screenSize|keyboard|orientation"
|
||||
android:label="@string/title_activity_featured_images"
|
||||
android:parentActivityName=".contributions.MainActivity" />
|
||||
<activity
|
||||
android:name=".explore.depictions.WikidataItemDetailsActivity"
|
||||
android:configChanges="screenSize|keyboard|orientation"
|
||||
android:label="@string/title_activity_featured_images"
|
||||
android:parentActivityName=".contributions.MainActivity" />
|
||||
<activity
|
||||
android:name=".explore.SearchActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:label="@string/title_activity_search"
|
||||
android:launchMode="singleTop"
|
||||
android:parentActivityName=".contributions.MainActivity" />
|
||||
<activity
|
||||
android:name=".profile.ProfileActivity"
|
||||
android:configChanges="orientation|screenSize|keyboard"
|
||||
android:label="@string/Profile" />
|
||||
<activity
|
||||
android:name=".review.ReviewActivity"
|
||||
android:label="@string/title_activity_review" />
|
||||
<activity
|
||||
android:name=".LocationPicker.LocationPickerActivity"
|
||||
android:label="Location Picker" />
|
||||
|
||||
<activity
|
||||
android:hardwareAccelerated="false"
|
||||
android:name=".upload.UploadActivity"
|
||||
android:exported="true"
|
||||
android:configChanges="orientation|screenSize|keyboard"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
>
|
||||
<intent-filter android:label="@string/intent_share_upload_label">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<service
|
||||
android:name=".auth.WikiAccountAuthenticatorService"
|
||||
android:exported="true"
|
||||
android:process=":auth">
|
||||
<intent-filter>
|
||||
<action android:name="android.accounts.AccountAuthenticator" />
|
||||
</intent-filter>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<meta-data
|
||||
android:name="android.accounts.AccountAuthenticator"
|
||||
android:resource="@xml/authenticator" />
|
||||
</service>
|
||||
<service
|
||||
android:name="org.acra.sender.SenderService"
|
||||
android:exported="false"
|
||||
android:process=":acra" />
|
||||
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="audio/ogg" />
|
||||
</intent-filter>
|
||||
<intent-filter android:label="@string/intent_share_upload_label">
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<provider
|
||||
android:name=".filepicker.ExtendedFileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths" />
|
||||
</provider>
|
||||
<provider
|
||||
android:name=".category.CategoryContentProvider"
|
||||
android:authorities="${applicationId}.categories.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_categories"
|
||||
android:syncable="false" />
|
||||
<provider
|
||||
android:name=".explore.recentsearches.RecentSearchesContentProvider"
|
||||
android:authorities="${applicationId}.explore.recentsearches.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_searches"
|
||||
android:syncable="false" />
|
||||
<provider
|
||||
android:name=".recentlanguages.RecentLanguagesContentProvider"
|
||||
android:authorities="${applicationId}.recentlanguages.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_recent_languages"
|
||||
android:syncable="false" />
|
||||
<provider
|
||||
android:name=".bookmarks.pictures.BookmarkPicturesContentProvider"
|
||||
android:authorities="${applicationId}.bookmarks.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_bookmarks"
|
||||
android:syncable="false" />
|
||||
<provider
|
||||
android:name=".bookmarks.locations.BookmarkLocationsContentProvider"
|
||||
android:authorities="${applicationId}.bookmarks.locations.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_bookmarks_location"
|
||||
android:syncable="false" />
|
||||
<provider
|
||||
android:name=".bookmarks.items.BookmarkItemsContentProvider"
|
||||
android:authorities="${applicationId}.bookmarks.items.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_bookmarks_location"
|
||||
android:syncable="false" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<receiver
|
||||
android:name=".widget.PicOfDayAppWidget"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="audio/ogg" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".contributions.MainActivity"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="screenSize|keyboard|orientation" />
|
||||
<activity
|
||||
android:name=".settings.SettingsActivity"
|
||||
android:label="@string/title_activity_settings" />
|
||||
<activity
|
||||
android:name=".AboutActivity"
|
||||
android:label="@string/title_activity_about"
|
||||
android:parentActivityName=".contributions.MainActivity" />
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/pic_of_day_app_widget_info" />
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name=".auth.SignupActivity"
|
||||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/title_activity_signup" />
|
||||
|
||||
<activity
|
||||
android:name=".notification.NotificationActivity"
|
||||
android:label="@string/navigation_item_notification" />
|
||||
|
||||
<activity android:name=".quiz.QuizActivity"
|
||||
android:label="@string/quiz"/>
|
||||
|
||||
<activity android:name=".quiz.QuizResultActivity"
|
||||
android:label="@string/result"/>
|
||||
|
||||
<activity
|
||||
android:name=".customselector.ui.selector.CustomSelectorActivity"
|
||||
android:label="@string/title_activity_custom_selector"
|
||||
android:configChanges="screenSize|keyboard|orientation"
|
||||
android:parentActivityName=".contributions.MainActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".category.CategoryDetailsActivity"
|
||||
android:label="@string/title_activity_featured_images"
|
||||
android:configChanges="screenSize|keyboard|orientation"
|
||||
android:parentActivityName=".contributions.MainActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".explore.depictions.WikidataItemDetailsActivity"
|
||||
android:label="@string/title_activity_featured_images"
|
||||
android:configChanges="screenSize|keyboard|orientation"
|
||||
android:parentActivityName=".contributions.MainActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".explore.SearchActivity"
|
||||
android:label="@string/title_activity_search"
|
||||
android:launchMode="singleTop"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:parentActivityName=".contributions.MainActivity"
|
||||
/>
|
||||
|
||||
<activity
|
||||
android:name=".profile.ProfileActivity"
|
||||
android:configChanges="orientation|screenSize|keyboard"
|
||||
android:label="@string/Profile" />
|
||||
|
||||
<activity
|
||||
android:name=".review.ReviewActivity"
|
||||
android:label="@string/title_activity_review" />
|
||||
|
||||
<activity
|
||||
android:name=".LocationPicker.LocationPickerActivity"
|
||||
android:label="Location Picker" />
|
||||
|
||||
<service
|
||||
android:name=".auth.WikiAccountAuthenticatorService"
|
||||
android:exported="true"
|
||||
android:process=":auth">
|
||||
<intent-filter>
|
||||
<action android:name="android.accounts.AccountAuthenticator" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.accounts.AccountAuthenticator"
|
||||
android:resource="@xml/authenticator" />
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name="org.acra.sender.SenderService"
|
||||
android:exported="false"
|
||||
android:process=":acra" />
|
||||
|
||||
<provider
|
||||
android:name=".filepicker.ExtendedFileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths" />
|
||||
</provider>
|
||||
|
||||
<provider
|
||||
android:name=".category.CategoryContentProvider"
|
||||
android:authorities="${applicationId}.categories.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_categories"
|
||||
android:syncable="false" />
|
||||
|
||||
<provider
|
||||
android:name=".explore.recentsearches.RecentSearchesContentProvider"
|
||||
android:authorities="${applicationId}.explore.recentsearches.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_searches"
|
||||
android:syncable="false" />
|
||||
|
||||
<provider
|
||||
android:name=".recentlanguages.RecentLanguagesContentProvider"
|
||||
android:authorities="${applicationId}.recentlanguages.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_recent_languages"
|
||||
android:syncable="false" />
|
||||
|
||||
<provider
|
||||
android:name=".bookmarks.pictures.BookmarkPicturesContentProvider"
|
||||
android:authorities="${applicationId}.bookmarks.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_bookmarks"
|
||||
android:syncable="false" />
|
||||
|
||||
<provider
|
||||
android:name=".bookmarks.locations.BookmarkLocationsContentProvider"
|
||||
android:authorities="${applicationId}.bookmarks.locations.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_bookmarks_location"
|
||||
android:syncable="false" />
|
||||
|
||||
<provider
|
||||
android:name=".bookmarks.items.BookmarkItemsContentProvider"
|
||||
android:authorities="${applicationId}.bookmarks.items.contentprovider"
|
||||
android:exported="false"
|
||||
android:label="@string/provider_bookmarks_location"
|
||||
android:syncable="false" />
|
||||
|
||||
<receiver android:name=".widget.PicOfDayAppWidget"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/pic_of_day_app_widget_info" />
|
||||
</receiver>
|
||||
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false" />
|
||||
|
||||
</application>
|
||||
<uses-library
|
||||
android:name="org.apache.http.legacy"
|
||||
android:required="false" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -20,6 +20,10 @@ public abstract class ContributionDao {
|
|||
@Query("SELECT * FROM contribution order by media_dateUploaded DESC")
|
||||
abstract DataSource.Factory<Integer, Contribution> fetchContributions();
|
||||
|
||||
@Query("SELECT * FROM contribution WHERE state = -1 ORDER BY media_dateUploaded DESC")
|
||||
abstract DataSource.Factory<Integer, Contribution> fetchContributionsWithStateCompleted();
|
||||
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
public abstract void saveSynchronous(Contribution contribution);
|
||||
|
||||
|
|
|
|||
|
|
@ -48,11 +48,8 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
|
||||
binding = LayoutContributionBinding.bind(parent);
|
||||
|
||||
binding.retryButton.setOnClickListener(v -> retryUpload());
|
||||
binding.cancelButton.setOnClickListener(v -> deleteUpload());
|
||||
binding.contributionImage.setOnClickListener(v -> imageClicked());
|
||||
binding.wikipediaButton.setOnClickListener(v -> wikipediaButtonClicked());
|
||||
binding.pauseResumeButton.setOnClickListener(v -> onPauseResumeButtonClicked());
|
||||
|
||||
/* Set a dialog indicating that the upload is being paused. This is needed because pausing
|
||||
an upload might take a dozen seconds. */
|
||||
|
|
@ -80,9 +77,6 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
binding.contributionImage.getHierarchy().setPlaceholderImage(R.drawable.image_placeholder);
|
||||
binding.contributionImage.getHierarchy().setFailureImage(R.drawable.image_placeholder);
|
||||
|
||||
|
||||
|
||||
|
||||
final String imageSource = chooseImageSource(contribution.getMedia().getThumbUrl(),
|
||||
contribution.getLocalUri());
|
||||
if (!TextUtils.isEmpty(imageSource)) {
|
||||
|
|
@ -90,79 +84,27 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(imageSource))
|
||||
.setProgressiveRenderingEnabled(true)
|
||||
.build();
|
||||
}
|
||||
else if (URLUtil.isFileUrl(imageSource)){
|
||||
imageRequest=ImageRequest.fromUri(Uri.parse(imageSource));
|
||||
}
|
||||
else if(imageSource != null) {
|
||||
} else if (URLUtil.isFileUrl(imageSource)) {
|
||||
imageRequest = ImageRequest.fromUri(Uri.parse(imageSource));
|
||||
} else if (imageSource != null) {
|
||||
final File file = new File(imageSource);
|
||||
imageRequest = ImageRequest.fromFile(file);
|
||||
}
|
||||
|
||||
if(imageRequest != null){
|
||||
if (imageRequest != null) {
|
||||
binding.contributionImage.setImageRequest(imageRequest);
|
||||
}
|
||||
}
|
||||
|
||||
binding.contributionSequenceNumber.setText(String.valueOf(position + 1));
|
||||
binding.contributionSequenceNumber.setVisibility(View.VISIBLE);
|
||||
|
||||
binding.wikipediaButton.setVisibility(View.GONE);
|
||||
switch (contribution.getState()) {
|
||||
case Contribution.STATE_COMPLETED:
|
||||
binding.contributionState.setVisibility(View.GONE);
|
||||
binding.contributionProgress.setVisibility(View.GONE);
|
||||
binding.imageOptions.setVisibility(View.GONE);
|
||||
binding.contributionState.setText("");
|
||||
checkIfMediaExistsOnWikipediaPage(contribution);
|
||||
break;
|
||||
case Contribution.STATE_QUEUED:
|
||||
case Contribution.STATE_QUEUED_LIMITED_CONNECTION_MODE:
|
||||
binding.contributionProgress.setVisibility(View.GONE);
|
||||
binding.contributionState.setVisibility(View.VISIBLE);
|
||||
binding.contributionState.setText(R.string.contribution_state_queued);
|
||||
binding.imageOptions.setVisibility(View.GONE);
|
||||
break;
|
||||
case Contribution.STATE_IN_PROGRESS:
|
||||
binding.contributionState.setVisibility(View.GONE);
|
||||
binding.contributionProgress.setVisibility(View.VISIBLE);
|
||||
binding.wikipediaButton.setVisibility(View.GONE);
|
||||
binding.pauseResumeButton.setVisibility(View.VISIBLE);
|
||||
binding.cancelButton.setVisibility(View.GONE);
|
||||
binding.retryButton.setVisibility(View.GONE);
|
||||
binding.imageOptions.setVisibility(View.VISIBLE);
|
||||
final long total = contribution.getDataLength();
|
||||
final long transferred = contribution.getTransferred();
|
||||
if (transferred == 0 || transferred >= total) {
|
||||
binding.contributionProgress.setIndeterminate(true);
|
||||
} else {
|
||||
binding.contributionProgress.setIndeterminate(false);
|
||||
binding.contributionProgress.setProgress((int) (((double) transferred / (double) total) * 100));
|
||||
}
|
||||
break;
|
||||
case Contribution.STATE_PAUSED:
|
||||
binding.contributionProgress.setVisibility(View.GONE);
|
||||
binding.contributionState.setVisibility(View.VISIBLE);
|
||||
binding.contributionState.setText(R.string.paused);
|
||||
binding.cancelButton.setVisibility(View.VISIBLE);
|
||||
binding.retryButton.setVisibility(View.GONE);
|
||||
binding.pauseResumeButton.setVisibility(View.VISIBLE);
|
||||
binding.imageOptions.setVisibility(View.VISIBLE);
|
||||
setResume();
|
||||
if(pausingPopUp.isShowing()){
|
||||
pausingPopUp.hide();
|
||||
}
|
||||
break;
|
||||
case Contribution.STATE_FAILED:
|
||||
binding.contributionState.setVisibility(View.VISIBLE);
|
||||
binding.contributionState.setText(R.string.contribution_state_failed);
|
||||
binding.contributionProgress.setVisibility(View.GONE);
|
||||
binding.cancelButton.setVisibility(View.VISIBLE);
|
||||
binding.retryButton.setVisibility(View.VISIBLE);
|
||||
binding.pauseResumeButton.setVisibility(View.GONE);
|
||||
binding.imageOptions.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
binding.contributionState.setVisibility(View.GONE);
|
||||
binding.contributionProgress.setVisibility(View.GONE);
|
||||
binding.imageOptions.setVisibility(View.GONE);
|
||||
binding.contributionState.setText("");
|
||||
checkIfMediaExistsOnWikipediaPage(contribution);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -196,8 +138,6 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
if (!mediaExists) {
|
||||
binding.wikipediaButton.setVisibility(View.VISIBLE);
|
||||
isWikipediaButtonDisplayed = true;
|
||||
binding.cancelButton.setVisibility(View.GONE);
|
||||
binding.retryButton.setVisibility(View.GONE);
|
||||
binding.imageOptions.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
|
@ -217,20 +157,6 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry upload when it is failed
|
||||
*/
|
||||
public void retryUpload() {
|
||||
callback.retryUpload(contribution);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a failed upload attempt
|
||||
*/
|
||||
public void deleteUpload() {
|
||||
callback.deleteUpload(contribution);
|
||||
}
|
||||
|
||||
public void imageClicked() {
|
||||
callback.openMediaDetail(position, isWikipediaButtonDisplayed);
|
||||
}
|
||||
|
|
@ -239,44 +165,6 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
callback.addImageToWikipedia(contribution);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a callback for pause/resume
|
||||
*/
|
||||
public void onPauseResumeButtonClicked() {
|
||||
if (binding.pauseResumeButton.getTag().toString().equals("pause")) {
|
||||
pause();
|
||||
} else {
|
||||
resume();
|
||||
}
|
||||
}
|
||||
|
||||
private void resume() {
|
||||
callback.resumeUpload(contribution);
|
||||
setPaused();
|
||||
}
|
||||
|
||||
private void pause() {
|
||||
pausingPopUp.show();
|
||||
callback.pauseUpload(contribution);
|
||||
setResume();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update pause/resume button to show pause state
|
||||
*/
|
||||
private void setPaused() {
|
||||
binding.pauseResumeButton.setImageResource(R.drawable.pause_icon);
|
||||
binding.pauseResumeButton.setTag(parent.getContext().getString(R.string.pause));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update pause/resume button to show resume state
|
||||
*/
|
||||
private void setResume() {
|
||||
binding.pauseResumeButton.setImageResource(R.drawable.play_icon);
|
||||
binding.pauseResumeButton.setTag(parent.getContext().getString(R.string.resume));
|
||||
}
|
||||
|
||||
public ImageRequest getImageRequest() {
|
||||
return imageRequest;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import android.Manifest;
|
|||
import android.Manifest.permission;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
|
|
@ -25,6 +26,7 @@ import android.view.MenuItem.OnMenuItemClickListener;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
|
@ -44,6 +46,7 @@ import fr.free.nrw.commons.notification.models.Notification;
|
|||
import fr.free.nrw.commons.notification.NotificationController;
|
||||
import fr.free.nrw.commons.profile.ProfileActivity;
|
||||
import fr.free.nrw.commons.theme.BaseActivity;
|
||||
import fr.free.nrw.commons.upload.UploadProgressActivity;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -129,6 +132,10 @@ public class ContributionsFragment
|
|||
|
||||
public TextView notificationCount;
|
||||
|
||||
public TextView pendingUploadsCountTextView;
|
||||
|
||||
public TextView uploadsErrorTextView;
|
||||
|
||||
private Campaign wlmCampaign;
|
||||
|
||||
String userName;
|
||||
|
|
@ -212,9 +219,7 @@ public class ContributionsFragment
|
|||
}
|
||||
|
||||
initFragments();
|
||||
if(isUserProfile) {
|
||||
binding.limitedConnectionEnabledLayout.setVisibility(View.GONE);
|
||||
}else {
|
||||
if(!isUserProfile) {
|
||||
upDateUploadCount();
|
||||
}
|
||||
if (shouldShowMediaDetailsFragment) {
|
||||
|
|
@ -230,7 +235,6 @@ public class ContributionsFragment
|
|||
&& sessionManager.getCurrentAccount() != null && !isUserProfile) {
|
||||
setUploadCount();
|
||||
}
|
||||
binding.limitedConnectionEnabledLayout.setOnClickListener(toggleDescriptionListener);
|
||||
setHasOptionsMenu(true);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
|
@ -258,10 +262,27 @@ public class ContributionsFragment
|
|||
MenuItem notificationsMenuItem = menu.findItem(R.id.notifications);
|
||||
final View notification = notificationsMenuItem.getActionView();
|
||||
notificationCount = notification.findViewById(R.id.notification_count_badge);
|
||||
MenuItem uploadMenuItem = menu.findItem(R.id.upload_tab);
|
||||
final View uploadMenuItemActionView = uploadMenuItem.getActionView();
|
||||
pendingUploadsCountTextView = uploadMenuItemActionView.findViewById(R.id.pending_uploads_count_badge);
|
||||
uploadsErrorTextView = uploadMenuItemActionView.findViewById(R.id.uploads_error_count_badge);
|
||||
final ImageView pendingUploadsImageView = uploadMenuItemActionView.findViewById(R.id.pending_uploads_image_view);
|
||||
|
||||
pendingUploadsImageView.setOnClickListener(view -> {
|
||||
startActivity(new Intent(getContext(), UploadProgressActivity.class));
|
||||
});
|
||||
|
||||
pendingUploadsCountTextView.setOnClickListener(view -> {
|
||||
startActivity(new Intent(getContext(), UploadProgressActivity.class));
|
||||
});
|
||||
|
||||
uploadsErrorTextView.setOnClickListener(view -> {
|
||||
startActivity(new Intent(getContext(), UploadProgressActivity.class));
|
||||
});
|
||||
|
||||
notification.setOnClickListener(view -> {
|
||||
NotificationActivity.startYourself(getContext(), "unread");
|
||||
});
|
||||
updateLimitedConnectionToggle(menu);
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
|
|
@ -289,29 +310,6 @@ public class ContributionsFragment
|
|||
}
|
||||
}
|
||||
|
||||
public void updateLimitedConnectionToggle(Menu menu) {
|
||||
MenuItem checkable = menu.findItem(R.id.toggle_limited_connection_mode);
|
||||
boolean isEnabled = store
|
||||
.getBoolean(CommonsApplication.IS_LIMITED_CONNECTION_MODE_ENABLED, false);
|
||||
|
||||
checkable.setChecked(isEnabled);
|
||||
if (binding!=null) {
|
||||
binding.limitedConnectionEnabledLayout.setVisibility(isEnabled ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
checkable.setIcon((isEnabled) ? R.drawable.ic_baseline_cloud_off_24:R.drawable.ic_baseline_cloud_queue_24);
|
||||
checkable.setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
((MainActivity) getActivity()).toggleLimitedConnectionMode();
|
||||
boolean isEnabled = store.getBoolean(CommonsApplication.IS_LIMITED_CONNECTION_MODE_ENABLED, false);
|
||||
binding.limitedConnectionEnabledLayout.setVisibility(isEnabled ? View.VISIBLE : View.GONE);
|
||||
checkable.setIcon((isEnabled) ? R.drawable.ic_baseline_cloud_off_24:R.drawable.ic_baseline_cloud_queue_24);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
|
|
@ -747,6 +745,26 @@ public class ContributionsFragment
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUploadsIcon(int pendingCount, int errorCount) {
|
||||
if (pendingUploadsCountTextView != null){
|
||||
if (pendingCount != 0){
|
||||
pendingUploadsCountTextView.setVisibility(View.VISIBLE);
|
||||
pendingUploadsCountTextView.setText(String.valueOf(pendingCount));
|
||||
}else {
|
||||
pendingUploadsCountTextView.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
if (errorCount != 0){
|
||||
uploadsErrorTextView.setVisibility(View.VISIBLE);
|
||||
uploadsErrorTextView.setText(String.valueOf(errorCount));
|
||||
}else {
|
||||
uploadsErrorTextView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace whatever is in the current contributionsFragmentContainer view with
|
||||
* mediaDetailPagerFragment, and preserve previous state in back stack. Called when user selects
|
||||
|
|
@ -844,21 +862,6 @@ public class ContributionsFragment
|
|||
}
|
||||
}
|
||||
|
||||
// click listener to toggle description that means uses can press the limited connection
|
||||
// banner and description will hide. Tap again to show description.
|
||||
private View.OnClickListener toggleDescriptionListener = new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
View view2 = binding.limitedConnectionDescriptionTextView;
|
||||
if (view2.getVisibility() == View.GONE) {
|
||||
view2.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
view2.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* When the device rotates, rotate the Nearby banner's compass arrow in tandem.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import android.view.animation.AnimationUtils;
|
|||
import android.widget.LinearLayout;
|
||||
import androidx.activity.result.ActivityResultCallback;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
|
@ -35,6 +35,7 @@ import fr.free.nrw.commons.Media;
|
|||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.Utils;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.contributions.ContributionsListAdapter.Callback;
|
||||
import fr.free.nrw.commons.databinding.FragmentContributionsListBinding;
|
||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.media.MediaClient;
|
||||
|
|
@ -49,6 +50,7 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import fr.free.nrw.commons.wikidata.model.WikiSite;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -56,7 +58,7 @@ import fr.free.nrw.commons.wikidata.model.WikiSite;
|
|||
*/
|
||||
|
||||
public class ContributionsListFragment extends CommonsDaggerSupportFragment implements
|
||||
ContributionsListContract.View, ContributionsListAdapter.Callback,
|
||||
ContributionsListContract.View, Callback,
|
||||
WikipediaInstructionsDialogFragment.Callback {
|
||||
|
||||
private static final String RV_STATE = "rv_scroll_state";
|
||||
|
|
@ -81,7 +83,8 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
|||
private Animation rotate_forward;
|
||||
private Animation rotate_backward;
|
||||
private boolean isFabOpen;
|
||||
|
||||
public int pendingUploadsCount = 0;
|
||||
public int uploadErrorCount = 0;
|
||||
@VisibleForTesting
|
||||
protected RecyclerView rvContributionsList;
|
||||
|
||||
|
|
@ -99,7 +102,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
|||
private String userName;
|
||||
|
||||
private ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.RequestMultiplePermissions(),
|
||||
new RequestMultiplePermissions(),
|
||||
new ActivityResultCallback<Map<String, Boolean>>() {
|
||||
@Override
|
||||
public void onActivityResult(Map<String, Boolean> result) {
|
||||
|
|
@ -214,6 +217,21 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
|||
|
||||
contributionsListPresenter.setup(userName,
|
||||
Objects.equals(sessionManager.getUserName(), userName));
|
||||
contributionsListPresenter.getTotalContribution(userName);
|
||||
contributionsListPresenter.totalContributionList.observe(getViewLifecycleOwner(), list -> {
|
||||
uploadErrorCount = 0;
|
||||
pendingUploadsCount = 0;
|
||||
for (int i = 0; i< list.size(); i++){
|
||||
if (list.get(i).getState() != Contribution.STATE_COMPLETED){
|
||||
if (list.get(i).getState() == Contribution.STATE_FAILED){
|
||||
uploadErrorCount++;
|
||||
}else {
|
||||
pendingUploadsCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
callback.updateUploadsIcon(pendingUploadsCount, uploadErrorCount);
|
||||
});
|
||||
contributionsListPresenter.contributionList.observe(getViewLifecycleOwner(), list -> {
|
||||
contributionsSize = list.size();
|
||||
adapter.submitList(list);
|
||||
|
|
@ -544,5 +562,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
|||
|
||||
// Notify the viewpager that number of items have changed.
|
||||
void viewPagerNotifyDataSetChanged();
|
||||
|
||||
void updateUploadsIcon(int pendingCount, int errorCount);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ public class ContributionsListPresenter implements UserActionListener {
|
|||
private final ContributionsRemoteDataSource contributionsRemoteDataSource;
|
||||
|
||||
LiveData<PagedList<Contribution>> contributionList;
|
||||
LiveData<PagedList<Contribution>> totalContributionList;
|
||||
|
||||
@Inject
|
||||
ContributionsListPresenter(
|
||||
|
|
@ -71,7 +72,7 @@ public class ContributionsListPresenter implements UserActionListener {
|
|||
} else {
|
||||
contributionBoundaryCallback.setUserName(userName);
|
||||
shouldSetBoundaryCallback = true;
|
||||
factory = repository.fetchContributions();
|
||||
factory = repository.fetchCompletedContributions();
|
||||
}
|
||||
|
||||
LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory, pagedListConfig);
|
||||
|
|
@ -100,4 +101,22 @@ public class ContributionsListPresenter implements UserActionListener {
|
|||
.subscribe());
|
||||
}
|
||||
|
||||
void getTotalContribution(String userName) {
|
||||
final PagedList.Config pagedListConfig =
|
||||
(new PagedList.Config.Builder())
|
||||
.setPrefetchDistance(50)
|
||||
.setPageSize(10).build();
|
||||
Factory<Integer, Contribution> factory;
|
||||
boolean shouldSetBoundaryCallback;
|
||||
contributionBoundaryCallback.setUserName(userName);
|
||||
shouldSetBoundaryCallback = true;
|
||||
factory = repository.fetchContributions();
|
||||
LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory,
|
||||
pagedListConfig);
|
||||
if (shouldSetBoundaryCallback) {
|
||||
livePagedListBuilder.setBoundaryCallback(contributionBoundaryCallback);
|
||||
}
|
||||
totalContributionList = livePagedListBuilder.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,10 @@ class ContributionsLocalDataSource {
|
|||
return contributionDao.fetchContributions();
|
||||
}
|
||||
|
||||
public Factory<Integer, Contribution> getCompletedContributions() {
|
||||
return contributionDao.fetchContributionsWithStateCompleted();
|
||||
}
|
||||
|
||||
public Single<List<Long>> saveContributions(final List<Contribution> contributions) {
|
||||
final List<Contribution> contributionList = new ArrayList<>();
|
||||
for(final Contribution contribution: contributions) {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,10 @@ public class ContributionsRepository {
|
|||
return localDataSource.getContributions();
|
||||
}
|
||||
|
||||
public Factory<Integer, Contribution> fetchCompletedContributions() {
|
||||
return localDataSource.getCompletedContributions();
|
||||
}
|
||||
|
||||
public Single<List<Long>> save(List<Contribution> contributions) {
|
||||
return localDataSource.saveContributions(contributions);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ import fr.free.nrw.commons.notification.NotificationController;
|
|||
import fr.free.nrw.commons.quiz.QuizChecker;
|
||||
import fr.free.nrw.commons.settings.SettingsFragment;
|
||||
import fr.free.nrw.commons.theme.BaseActivity;
|
||||
import fr.free.nrw.commons.upload.UploadActivity;
|
||||
import fr.free.nrw.commons.upload.UploadProgressActivity;
|
||||
import fr.free.nrw.commons.upload.worker.WorkRequestHelper;
|
||||
import fr.free.nrw.commons.utils.PermissionUtils;
|
||||
import fr.free.nrw.commons.utils.ViewUtilWrapper;
|
||||
|
|
@ -385,6 +387,9 @@ public class MainActivity extends BaseActivity
|
|||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.upload_tab:
|
||||
startActivity(new Intent(this, UploadProgressActivity.class));
|
||||
return true;
|
||||
case R.id.notifications:
|
||||
// Starts notification activity on click to notification icon
|
||||
NotificationActivity.startYourself(this, "unread");
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import fr.free.nrw.commons.profile.ProfileActivity;
|
|||
import fr.free.nrw.commons.review.ReviewActivity;
|
||||
import fr.free.nrw.commons.settings.SettingsActivity;
|
||||
import fr.free.nrw.commons.upload.UploadActivity;
|
||||
import fr.free.nrw.commons.upload.UploadProgressActivity;
|
||||
|
||||
/**
|
||||
* This Class handles the dependency injection (using dagger)
|
||||
|
|
@ -79,4 +80,7 @@ public abstract class ActivityBuilderModule {
|
|||
|
||||
@ContributesAndroidInjector
|
||||
abstract ZoomableActivity bindZoomableActivity();
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract UploadProgressActivity bindUploadProgressActivity();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import fr.free.nrw.commons.profile.achievements.AchievementsFragment;
|
|||
import fr.free.nrw.commons.profile.leaderboard.LeaderboardFragment;
|
||||
import fr.free.nrw.commons.review.ReviewImageFragment;
|
||||
import fr.free.nrw.commons.settings.SettingsFragment;
|
||||
import fr.free.nrw.commons.upload.PendingUploadsFragment;
|
||||
import fr.free.nrw.commons.upload.categories.UploadCategoriesFragment;
|
||||
import fr.free.nrw.commons.upload.depicts.DepictsFragment;
|
||||
import fr.free.nrw.commons.upload.license.MediaLicenseFragment;
|
||||
|
|
@ -155,4 +156,7 @@ public abstract class FragmentBuilderModule {
|
|||
|
||||
@ContributesAndroidInjector
|
||||
abstract LeaderboardFragment bindLeaderboardFragment();
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract PendingUploadsFragment bindPendingUploadsFragment();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
package fr.free.nrw.commons.upload
|
||||
|
||||
|
||||
data class PendingUploadItem(var title: String, var image: String, var queued : Boolean ,var error:String)
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
package fr.free.nrw.commons.upload
|
||||
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.URLUtil
|
||||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.facebook.imagepipeline.request.ImageRequest
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.contributions.Contribution
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
|
||||
class PendingUploadsAdapter(items: List<Contribution>, callback: Callback) :
|
||||
RecyclerView.Adapter<PendingUploadsAdapter.ViewHolder>() {
|
||||
private val items: List<Contribution> = items
|
||||
private var callback:Callback = callback
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view: View =
|
||||
LayoutInflater.from(parent.context).inflate(R.layout.item_pending_upload, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item: Contribution = items[position]
|
||||
holder.titleTextView.setText(item.media.displayTitle)
|
||||
var imageRequest: ImageRequest? = null
|
||||
|
||||
val imageSource: String = item.localUri.toString()
|
||||
Timber.tag("PRINT").e("--"+imageSource)
|
||||
|
||||
if (!TextUtils.isEmpty(imageSource)) {
|
||||
if (URLUtil.isFileUrl(imageSource)) {
|
||||
imageRequest = ImageRequest.fromUri(Uri.parse(imageSource))!!
|
||||
} else if (imageSource != null) {
|
||||
val file = File(imageSource)
|
||||
imageRequest = ImageRequest.fromFile(file)!!
|
||||
}
|
||||
|
||||
if (imageRequest != null) {
|
||||
holder.itemImage.setImageRequest(imageRequest)
|
||||
}
|
||||
}
|
||||
|
||||
if (item.state == Contribution.STATE_QUEUED || item.state == Contribution.STATE_PAUSED) {
|
||||
holder.errorTextView.setText("Queued")
|
||||
holder.errorTextView.visibility = View.VISIBLE
|
||||
holder.itemProgress.visibility = View.GONE
|
||||
} else {
|
||||
holder.errorTextView.visibility = View.GONE
|
||||
holder.itemProgress.visibility = View.VISIBLE
|
||||
val total: Long = item.dataLength
|
||||
val transferred: Long = item.transferred
|
||||
if (transferred == 0L || transferred >= total) {
|
||||
holder.itemProgress.setIndeterminate(true)
|
||||
} else {
|
||||
holder.itemProgress.setIndeterminate(false)
|
||||
holder.itemProgress.setProgress(((transferred.toDouble() / total.toDouble()) * 100).toInt())
|
||||
}
|
||||
}
|
||||
|
||||
holder.itemImage.setImageRequest(imageRequest)
|
||||
|
||||
holder.deleteButton.setOnClickListener{
|
||||
callback!!.deleteUpload(item)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return items.size
|
||||
}
|
||||
|
||||
|
||||
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
var itemImage: com.facebook.drawee.view.SimpleDraweeView = itemView.findViewById(R.id.itemImage)
|
||||
var titleTextView: TextView = itemView.findViewById<TextView>(R.id.titleTextView)
|
||||
var itemProgress: ProgressBar = itemView.findViewById<ProgressBar>(R.id.itemProgress)
|
||||
var errorTextView: TextView = itemView.findViewById<TextView>(R.id.errorTextView)
|
||||
var deleteButton: ImageView = itemView.findViewById(R.id.deleteButton)
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
fun deleteUpload(contribution: Contribution?)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package fr.free.nrw.commons.upload;
|
||||
|
||||
import fr.free.nrw.commons.BasePresenter;
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
|
||||
public class PendingUploadsContract {
|
||||
|
||||
public interface View {
|
||||
|
||||
void showWelcomeTip(boolean numberOfUploads);
|
||||
|
||||
void showProgress(boolean shouldShow);
|
||||
|
||||
void showNoContributionsUI(boolean shouldShow);
|
||||
}
|
||||
|
||||
public interface UserActionListener extends
|
||||
BasePresenter<fr.free.nrw.commons.upload.PendingUploadsContract.View> {
|
||||
|
||||
void deleteUpload(Contribution contribution);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
package fr.free.nrw.commons.upload
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.paging.PagedList
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import fr.free.nrw.commons.CommonsApplication
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.contributions.Contribution
|
||||
import fr.free.nrw.commons.databinding.FragmentPendingUploadsBinding
|
||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
|
||||
import fr.free.nrw.commons.media.MediaClient
|
||||
import fr.free.nrw.commons.profile.ProfileActivity
|
||||
import fr.free.nrw.commons.utils.DialogUtil.showAlertDialog
|
||||
import fr.free.nrw.commons.utils.ViewUtil
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
import timber.log.Timber
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* A simple [Fragment] subclass.
|
||||
* Use the [PendingUploadsFragment.newInstance] factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
class PendingUploadsFragment : CommonsDaggerSupportFragment(), PendingUploadsContract.View,
|
||||
PendingUploadsAdapter.Callback {
|
||||
var isPendingIconsVisible = false
|
||||
|
||||
// TODO: Rename and change types of parameters
|
||||
private var param1: String? = null
|
||||
private var param2: String? = null
|
||||
private val ARG_PARAM1 = "param1"
|
||||
private val ARG_PARAM2 = "param2"
|
||||
|
||||
@Inject
|
||||
lateinit var pendingUploadsPresenter: PendingUploadsPresenter
|
||||
|
||||
@Inject
|
||||
lateinit var mediaClient: MediaClient
|
||||
|
||||
@Inject
|
||||
lateinit var sessionManager: SessionManager
|
||||
|
||||
private var userName: String? = null
|
||||
|
||||
private lateinit var binding: FragmentPendingUploadsBinding
|
||||
|
||||
private lateinit var uploadProgressActivity: UploadProgressActivity
|
||||
|
||||
private var contributionsSize = 0
|
||||
var l = ArrayList<Contribution>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.let {
|
||||
param1 = it.getString(ARG_PARAM1)
|
||||
param2 = it.getString(ARG_PARAM2)
|
||||
}
|
||||
|
||||
//Now that we are allowing this fragment to be started for
|
||||
// any userName- we expect it to be passed as an argument
|
||||
if (arguments != null) {
|
||||
userName = requireArguments().getString(ProfileActivity.KEY_USERNAME)
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(userName)) {
|
||||
userName = sessionManager!!.getUserName()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
if (context is UploadProgressActivity) {
|
||||
uploadProgressActivity = context
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = FragmentPendingUploadsBinding.inflate(inflater, container, false)
|
||||
pendingUploadsPresenter.onAttachView(this)
|
||||
initRecyclerView()
|
||||
return binding.root
|
||||
}
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
}
|
||||
|
||||
fun initRecyclerView() {
|
||||
binding.pendingUploadsRecyclerView.setLayoutManager(LinearLayoutManager(this.context))
|
||||
pendingUploadsPresenter!!.setup(
|
||||
userName,
|
||||
sessionManager!!.userName == userName
|
||||
)
|
||||
pendingUploadsPresenter!!.totalContributionList.observe(
|
||||
viewLifecycleOwner
|
||||
) { list: PagedList<Contribution?> ->
|
||||
contributionsSize = list.size
|
||||
l = ArrayList()
|
||||
var x = 0;
|
||||
list.forEach {
|
||||
if (it!!.state == Contribution.STATE_PAUSED
|
||||
|| it.state == Contribution.STATE_QUEUED
|
||||
|| it.state == Contribution.STATE_IN_PROGRESS
|
||||
) {
|
||||
l.add(it)
|
||||
}
|
||||
if (it!!.state == Contribution.STATE_PAUSED
|
||||
|| it.state == Contribution.STATE_QUEUED
|
||||
) {
|
||||
x++
|
||||
}
|
||||
}
|
||||
Timber.tag("PRINT").e(l.size.toString())
|
||||
if (l.size == 0) {
|
||||
binding.nopendingTextView.visibility = View.VISIBLE
|
||||
binding.pendingUplaodsLl.visibility = View.GONE
|
||||
uploadProgressActivity.hidePendingIcons()
|
||||
} else {
|
||||
binding.nopendingTextView.visibility = View.GONE
|
||||
binding.pendingUplaodsLl.visibility = View.VISIBLE
|
||||
val adapter = PendingUploadsAdapter(l, this)
|
||||
binding.pendingUploadsRecyclerView.setAdapter(adapter)
|
||||
binding.progressTextView.setText("0/" + l.size + " uploaded")
|
||||
|
||||
if (x == l.size) {
|
||||
uploadProgressActivity.setPausedIcon(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun deleteUpload(contribution: Contribution?) {
|
||||
showAlertDialog(
|
||||
requireActivity(),
|
||||
String.format(
|
||||
Locale.getDefault(),
|
||||
getString(R.string.cancelling_upload)
|
||||
),
|
||||
String.format(
|
||||
Locale.getDefault(),
|
||||
getString(R.string.cancel_upload_dialog)
|
||||
),
|
||||
String.format(Locale.getDefault(), getString(R.string.yes)),
|
||||
String.format(Locale.getDefault(), getString(R.string.no)),
|
||||
{
|
||||
ViewUtil.showShortToast(context, R.string.cancelling_upload)
|
||||
pendingUploadsPresenter.deleteUpload(contribution)
|
||||
CommonsApplication.cancelledUploads.add(contribution!!.pageId)
|
||||
},
|
||||
{}
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Use this factory method to create a new instance of
|
||||
* this fragment using the provided parameters.
|
||||
*
|
||||
* @param param1 Parameter 1.
|
||||
* @param param2 Parameter 2.
|
||||
* @return A new instance of fragment PendingUploadsFragment.
|
||||
*/
|
||||
// TODO: Rename and change types and number of parameters
|
||||
@JvmStatic
|
||||
fun newInstance(param1: String, param2: String) =
|
||||
PendingUploadsFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString(ARG_PARAM1, param1)
|
||||
putString(ARG_PARAM2, param2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun showWelcomeTip(numberOfUploads: Boolean) {
|
||||
//TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun showProgress(shouldShow: Boolean) {
|
||||
//TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun showNoContributionsUI(shouldShow: Boolean) {
|
||||
//TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
fun restartUpload() {
|
||||
var contribution = l.get(0)
|
||||
contribution.state = Contribution.STATE_QUEUED
|
||||
pendingUploadsPresenter.saveContribution(contribution, this.requireContext().applicationContext)
|
||||
Timber.d("Restarting for %s", contribution.toString())
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
package fr.free.nrw.commons.upload;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.paging.DataSource;
|
||||
import androidx.paging.DataSource.Factory;
|
||||
import androidx.paging.LivePagedListBuilder;
|
||||
import androidx.paging.PagedList;
|
||||
import androidx.work.ExistingWorkPolicy;
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
import fr.free.nrw.commons.contributions.ContributionBoundaryCallback;
|
||||
import fr.free.nrw.commons.contributions.ContributionsRemoteDataSource;
|
||||
import fr.free.nrw.commons.contributions.ContributionsRepository;
|
||||
import fr.free.nrw.commons.di.CommonsApplicationModule;
|
||||
import fr.free.nrw.commons.upload.PendingUploadsContract.UserActionListener;
|
||||
import fr.free.nrw.commons.upload.PendingUploadsContract.View;
|
||||
import fr.free.nrw.commons.upload.worker.WorkRequestHelper;
|
||||
import io.reactivex.Scheduler;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* The presenter class for Contributions
|
||||
*/
|
||||
public class PendingUploadsPresenter implements UserActionListener {
|
||||
|
||||
private final ContributionBoundaryCallback contributionBoundaryCallback;
|
||||
private final ContributionsRepository repository;
|
||||
private final Scheduler ioThreadScheduler;
|
||||
|
||||
private final CompositeDisposable compositeDisposable;
|
||||
private final ContributionsRemoteDataSource contributionsRemoteDataSource;
|
||||
|
||||
LiveData<PagedList<Contribution>> totalContributionList;
|
||||
|
||||
@Inject
|
||||
PendingUploadsPresenter(
|
||||
final ContributionBoundaryCallback contributionBoundaryCallback,
|
||||
final ContributionsRemoteDataSource contributionsRemoteDataSource,
|
||||
final ContributionsRepository repository,
|
||||
@Named(CommonsApplicationModule.IO_THREAD) final Scheduler ioThreadScheduler) {
|
||||
this.contributionBoundaryCallback = contributionBoundaryCallback;
|
||||
this.repository = repository;
|
||||
this.ioThreadScheduler = ioThreadScheduler;
|
||||
this.contributionsRemoteDataSource=contributionsRemoteDataSource;
|
||||
compositeDisposable = new CompositeDisposable();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setup the paged list. This method sets the configuration for paged list and ties it up with
|
||||
* the live data object. This method can be tweaked to update the lazy loading behavior of the
|
||||
* contributions list
|
||||
*/
|
||||
void setup(String userName, boolean isSelf) {
|
||||
final PagedList.Config pagedListConfig =
|
||||
(new PagedList.Config.Builder())
|
||||
.setPrefetchDistance(50)
|
||||
.setPageSize(10).build();
|
||||
Factory<Integer, Contribution> factory;
|
||||
boolean shouldSetBoundaryCallback;
|
||||
if (!isSelf) {
|
||||
//We don't want to persist contributions for other user's, therefore
|
||||
// creating a new DataSource for them
|
||||
contributionsRemoteDataSource.setUserName(userName);
|
||||
factory = new Factory<Integer, Contribution>() {
|
||||
@NonNull
|
||||
@Override
|
||||
public DataSource<Integer, Contribution> create() {
|
||||
return contributionsRemoteDataSource;
|
||||
}
|
||||
};
|
||||
shouldSetBoundaryCallback = false;
|
||||
} else {
|
||||
contributionBoundaryCallback.setUserName(userName);
|
||||
shouldSetBoundaryCallback = true;
|
||||
factory = repository.fetchContributions();
|
||||
}
|
||||
|
||||
LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory, pagedListConfig);
|
||||
if (shouldSetBoundaryCallback) {
|
||||
livePagedListBuilder.setBoundaryCallback(contributionBoundaryCallback);
|
||||
}
|
||||
|
||||
totalContributionList = livePagedListBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachView(@NonNull View view) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDetachView() {
|
||||
compositeDisposable.clear();
|
||||
contributionsRemoteDataSource.dispose();
|
||||
contributionBoundaryCallback.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a failed contribution from the local db
|
||||
*/
|
||||
@Override
|
||||
public void deleteUpload(final Contribution contribution) {
|
||||
compositeDisposable.add(repository
|
||||
.deleteContributionFromDB(contribution)
|
||||
.subscribeOn(ioThreadScheduler)
|
||||
.subscribe());
|
||||
}
|
||||
|
||||
public void saveContribution(Contribution contribution, Context context) {
|
||||
compositeDisposable.add(repository
|
||||
.save(contribution)
|
||||
.subscribeOn(ioThreadScheduler)
|
||||
.subscribe(() ->
|
||||
WorkRequestHelper.Companion.makeOneTimeWorkRequest(
|
||||
context, ExistingWorkPolicy.KEEP)
|
||||
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
package fr.free.nrw.commons.upload
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.ViewPagerAdapter
|
||||
import fr.free.nrw.commons.contributions.Contribution
|
||||
import fr.free.nrw.commons.databinding.ActivityUploadProgressBinding
|
||||
import fr.free.nrw.commons.theme.BaseActivity
|
||||
import fr.free.nrw.commons.upload.fragments.FailedUploadsFragment
|
||||
import fr.free.nrw.commons.upload.worker.WorkRequestHelper.Companion.makeOneTimeWorkRequest
|
||||
import fr.free.nrw.commons.utils.NetworkUtils
|
||||
import fr.free.nrw.commons.utils.ViewUtil
|
||||
import io.reactivex.functions.Action
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class UploadProgressActivity : BaseActivity() {
|
||||
|
||||
private lateinit var binding: ActivityUploadProgressBinding
|
||||
private var pendingUploadsFragment: PendingUploadsFragment? = null
|
||||
private var failedUploadsFragment: FailedUploadsFragment? = null
|
||||
var viewPagerAdapter: ViewPagerAdapter? = null
|
||||
var menu: Menu? = null
|
||||
val fragmentList: MutableList<Fragment> = ArrayList()
|
||||
val titleList: MutableList<String> = ArrayList()
|
||||
var isPaused = true
|
||||
var isPendingIconsVisible = true
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityUploadProgressBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
viewPagerAdapter = ViewPagerAdapter(supportFragmentManager)
|
||||
binding.uploadProgressViewPager.setAdapter(viewPagerAdapter)
|
||||
binding.uploadProgressViewPager.setId(R.id.upload_progress_view_pager)
|
||||
binding.uploadProgressTabLayout.setupWithViewPager(binding.uploadProgressViewPager)
|
||||
binding.toolbarBinding.toolbar.title = "Uploads"
|
||||
setSupportActionBar(binding.toolbarBinding.toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
|
||||
binding.uploadProgressViewPager.addOnPageChangeListener(object :
|
||||
ViewPager.OnPageChangeListener {
|
||||
override fun onPageScrolled(
|
||||
position: Int, positionOffset: Float,
|
||||
positionOffsetPixels: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
updateMenuItems(position)
|
||||
if (position == 2) {
|
||||
binding.uploadProgressViewPager.setCanScroll(false)
|
||||
} else {
|
||||
binding.uploadProgressViewPager.setCanScroll(true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
}
|
||||
})
|
||||
setTabs()
|
||||
}
|
||||
|
||||
fun setTabs() {
|
||||
pendingUploadsFragment = PendingUploadsFragment()
|
||||
failedUploadsFragment = FailedUploadsFragment()
|
||||
|
||||
fragmentList.add(pendingUploadsFragment!!)
|
||||
titleList.add("Pending")
|
||||
fragmentList.add(failedUploadsFragment!!)
|
||||
titleList.add("Failed")
|
||||
viewPagerAdapter!!.setTabData(fragmentList, titleList)
|
||||
viewPagerAdapter!!.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_uploads,menu)
|
||||
this.menu = menu
|
||||
updateMenuItems(0)
|
||||
return super.onCreateOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
onBackPressed()
|
||||
return true
|
||||
}
|
||||
|
||||
fun updateMenuItems(currentPosition: Int) {
|
||||
if (currentPosition == 0) {
|
||||
if (isPendingIconsVisible){
|
||||
menu!!.removeItem(R.id.retry_icon)
|
||||
menu!!.removeItem(R.id.cancel_icon)
|
||||
menu!!.removeItem(R.id.pause_icon)
|
||||
menu!!.removeItem(R.id.resume_icon)
|
||||
if (!isPaused){
|
||||
if (menu!!.findItem(R.id.pause_icon) == null) {
|
||||
menu!!.add(Menu.NONE, R.id.pause_icon, Menu.NONE, "Pause")
|
||||
.setIcon(android.R.drawable.ic_media_pause).setOnMenuItemClickListener {
|
||||
setPausedIcon(true)
|
||||
true
|
||||
}
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
|
||||
}
|
||||
if (menu!!.findItem(R.id.cancel_icon) == null) {
|
||||
menu!!.add(Menu.NONE, R.id.cancel_icon, Menu.NONE, "Cancel")
|
||||
.setIcon(android.R.drawable.ic_menu_close_clear_cancel).setOnMenuItemClickListener {
|
||||
hidePendingIcons()
|
||||
true
|
||||
}
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
|
||||
}
|
||||
}else{
|
||||
if (menu!!.findItem(R.id.resume_icon) == null) {
|
||||
menu!!.add(Menu.NONE, R.id.resume_icon, Menu.NONE, "Resume")
|
||||
.setIcon(android.R.drawable.ic_media_play).setOnMenuItemClickListener {
|
||||
pendingUploadsFragment!!.restartUpload()
|
||||
setPausedIcon(false)
|
||||
true
|
||||
}
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
|
||||
}
|
||||
}
|
||||
}else{
|
||||
menu!!.removeItem(R.id.retry_icon)
|
||||
menu!!.removeItem(R.id.pause_icon)
|
||||
menu!!.removeItem(R.id.resume_icon)
|
||||
menu!!.removeItem(R.id.cancel_icon)
|
||||
}
|
||||
} else if (currentPosition == 1) {
|
||||
menu!!.removeItem(R.id.pause_icon)
|
||||
if (menu!!.findItem(R.id.retry_icon) == null) {
|
||||
menu!!.add(Menu.NONE, R.id.retry_icon, Menu.NONE, "Retry")
|
||||
.setIcon(R.drawable.ic_refresh_white_24dp)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun hidePendingIcons() {
|
||||
isPendingIconsVisible = false
|
||||
updateMenuItems(binding.uploadProgressViewPager.currentItem)
|
||||
}
|
||||
|
||||
fun setPausedIcon(paused : Boolean){
|
||||
isPaused = paused
|
||||
updateMenuItems(binding.uploadProgressViewPager.currentItem)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package fr.free.nrw.commons.upload.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import fr.free.nrw.commons.R
|
||||
|
||||
// TODO: Rename parameter arguments, choose names that match
|
||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||
private const val ARG_PARAM1 = "param1"
|
||||
private const val ARG_PARAM2 = "param2"
|
||||
|
||||
/**
|
||||
* A simple [Fragment] subclass.
|
||||
* Use the [FailedUploadsFragment.newInstance] factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
class FailedUploadsFragment : Fragment() {
|
||||
// TODO: Rename and change types of parameters
|
||||
private var param1: String? = null
|
||||
private var param2: String? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.let {
|
||||
param1 = it.getString(ARG_PARAM1)
|
||||
param2 = it.getString(ARG_PARAM2)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.fragment_failed_uploads, container, false)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Use this factory method to create a new instance of
|
||||
* this fragment using the provided parameters.
|
||||
*
|
||||
* @param param1 Parameter 1.
|
||||
* @param param2 Parameter 2.
|
||||
* @return A new instance of fragment FailedUploadsFragment.
|
||||
*/
|
||||
// TODO: Rename and change types and number of parameters
|
||||
@JvmStatic
|
||||
fun newInstance(param1: String, param2: String) =
|
||||
FailedUploadsFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString(ARG_PARAM1, param1)
|
||||
putString(ARG_PARAM2, param2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package fr.free.nrw.commons.upload.fragments
|
||||
|
||||
|
||||
// TODO: Rename parameter arguments, choose names that match
|
||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||
|
||||
|
||||
56
app/src/main/res/layout/activity_upload_progress.xml
Normal file
56
app/src/main/res/layout/activity_upload_progress.xml
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".upload.UploadProgressActivity">
|
||||
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbarBinding"
|
||||
layout="@layout/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/upload_progress_toolbar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/card_light_grey">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/upload_progress_tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/toolbar"
|
||||
android:background="?attr/tabBackground"
|
||||
app:tabIndicatorColor="?attr/tabIndicatorColor"
|
||||
app:tabMode="fixed"
|
||||
app:tabSelectedTextColor="?attr/tabSelectedTextColor"
|
||||
app:tabTextColor="?attr/tabTextColor" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<!-- <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"-->
|
||||
<!-- android:id="@+id/mediaContainer"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="match_parent"-->
|
||||
<!-- android:layout_below="@id/toolbar_layout"-->
|
||||
<!-- android:orientation="horizontal"-->
|
||||
<!-- android:visibility="gone" />-->
|
||||
|
||||
<fr.free.nrw.commons.explore.ParentViewPager
|
||||
android:id="@+id/upload_progress_view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/upload_progress_toolbar_layout"
|
||||
android:background="?attr/mainBackground" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -18,36 +18,6 @@
|
|||
android:layout_marginTop="@dimen/miniscule_margin"
|
||||
android:layout_margin="@dimen/very_tiny_gap"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/limited_connection_enabled_layout"
|
||||
android:animateLayoutChanges="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/miniscule_margin"
|
||||
android:padding="@dimen/standard_gap"
|
||||
android:orientation="vertical"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="@color/wikimedia_green">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:layout_marginBottom="@dimen/tiny_gap"
|
||||
android:textSize="@dimen/subheading_text_size"
|
||||
android:text="@string/limited_connection_is_on"
|
||||
app:drawableTint="@color/white"
|
||||
app:drawableStartCompat="@drawable/ic_baseline_cloud_off_24"/>
|
||||
<TextView
|
||||
android:id="@+id/limited_connection_description_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/description_text_size"
|
||||
android:text="@string/limited_connection_explanation"/>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/explore_container"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
14
app/src/main/res/layout/fragment_failed_uploads.xml
Normal file
14
app/src/main/res/layout/fragment_failed_uploads.xml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".upload.fragments.FailedUploadsFragment">
|
||||
|
||||
<!-- TODO: Update blank fragment layout -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/hello_blank_fragment" />
|
||||
|
||||
</FrameLayout>
|
||||
69
app/src/main/res/layout/fragment_pending_uploads.xml
Normal file
69
app/src/main/res/layout/fragment_pending_uploads.xml
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
tools:context=".upload.PendingUploadsFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nopendingTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="You do not have any pending Uploads!" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/pendingUplaodsLl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:gravity="bottom"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:text="Progress:"
|
||||
android:textSize="22sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/progress_text_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0/2 uploaded" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBarPending"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/pending_uploads_recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginHorizontal="10dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
55
app/src/main/res/layout/item_pending_upload.xml
Normal file
55
app/src/main/res/layout/item_pending_upload.xml
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:fresco="http://schemas.android.com/tools"
|
||||
android:paddingBottom="8dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:id="@+id/itemImage"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="?attr/mainBackground"
|
||||
app:actualImageScaleType="centerCrop"
|
||||
fresco:placeholderImage="@drawable/ic_image_black_24dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="6dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="24sp"
|
||||
android:text="RandomTest" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/itemProgress"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/errorTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Queued"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/deleteButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@android:drawable/ic_menu_close_clear_cancel" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -104,40 +104,6 @@
|
|||
android:paddingTop="@dimen/standard_gap"
|
||||
android:visibility="visible">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/pauseResumeButton"
|
||||
android:layout_width="@dimen/dimen_40"
|
||||
android:layout_height="@dimen/dimen_40"
|
||||
android:layout_marginEnd="@dimen/tiny_padding"
|
||||
android:layout_toStartOf="@id/cancelButton"
|
||||
android:background="@android:color/transparent"
|
||||
android:tag="@string/pause"
|
||||
app:srcCompat="@drawable/pause_icon" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="@dimen/tiny_padding"
|
||||
android:layout_toStartOf="@id/retryButton"
|
||||
android:background="@android:color/transparent"
|
||||
android:padding="@dimen/activity_margin_horizontal"
|
||||
android:src="@drawable/ic_cancel_white"
|
||||
android:tint="?attr/contributionsListTextSecondary"
|
||||
android:text="@string/menu_cancel_upload" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/retryButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="@dimen/tiny_padding"
|
||||
android:layout_toStartOf="@id/wikipediaButton"
|
||||
android:background="@android:color/transparent"
|
||||
android:padding="@dimen/activity_margin_horizontal"
|
||||
android:src="@drawable/ic_retry_white"
|
||||
android:tint="?attr/contributionsListTextSecondary"
|
||||
android:text="@string/menu_retry_upload" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/wikipediaButton"
|
||||
android:layout_width="48dp"
|
||||
|
|
|
|||
59
app/src/main/res/layout/pending_uploads_icon.xml
Normal file
59
app/src/main/res/layout/pending_uploads_icon.xml
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
tools:background="@color/black">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/pending_uploads_image_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
||||
android:gravity="center"
|
||||
app:srcCompat="@android:drawable/stat_sys_upload" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pending_uploads_count_badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/pending_uploads_image_view"
|
||||
android:layout_alignEnd="@id/pending_uploads_image_view"
|
||||
android:layout_alignRight="@id/pending_uploads_image_view"
|
||||
android:background="@drawable/notification_badge"
|
||||
android:gravity="center"
|
||||
android:padding="@dimen/miniscule_margin"
|
||||
android:textColor="?attr/notification_icon_text_color"
|
||||
android:textSize="7sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
tools:text="9+"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/uploads_error_count_badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/pending_uploads_count_badge"
|
||||
android:layout_alignEnd="@id/pending_uploads_image_view"
|
||||
android:layout_alignRight="@id/pending_uploads_image_view"
|
||||
android:layout_marginTop="1dp"
|
||||
android:layout_marginEnd="0dp"
|
||||
android:layout_marginRight="0dp"
|
||||
android:background="@drawable/notification_badge"
|
||||
android:backgroundTint="@color/button_blue"
|
||||
android:gravity="center"
|
||||
android:padding="@dimen/miniscule_margin"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="7sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
tools:text="9+"
|
||||
tools:visibility="visible" />
|
||||
</RelativeLayout>
|
||||
|
|
@ -1,16 +1,14 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item android:id="@+id/toggle_limited_connection_mode"
|
||||
android:title="@string/limited_connection_mode"
|
||||
app:showAsAction="always"
|
||||
android:checkable="true"
|
||||
android:icon="@drawable/ic_baseline_cloud_queue_24"
|
||||
/>
|
||||
<item android:id="@+id/notifications"
|
||||
android:title="@string/notifications"
|
||||
app:showAsAction="ifRoom|withText"
|
||||
android:menuCategory="secondary"
|
||||
app:actionLayout="@layout/notification_icon"
|
||||
/>
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/upload_tab"
|
||||
android:title="Upload"
|
||||
app:actionLayout="@layout/pending_uploads_icon"
|
||||
app:showAsAction="ifRoom|withText" />
|
||||
<item
|
||||
android:id="@+id/notifications"
|
||||
android:menuCategory="secondary"
|
||||
android:title="@string/notifications"
|
||||
app:actionLayout="@layout/notification_icon"
|
||||
app:showAsAction="ifRoom|withText" />
|
||||
</menu>
|
||||
|
|
|
|||
37
app/src/main/res/menu/menu_uploads.xml
Normal file
37
app/src/main/res/menu/menu_uploads.xml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".upload.UploadProgressActivity"
|
||||
>
|
||||
<item
|
||||
android:id="@+id/resume_icon"
|
||||
android:title="Resume"
|
||||
android:icon="@android:drawable/ic_media_play"
|
||||
android:orderInCategory="1"
|
||||
app:showAsAction="ifRoom"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/pause_icon"
|
||||
android:title="Pause"
|
||||
android:icon="@android:drawable/ic_media_pause"
|
||||
android:orderInCategory="1"
|
||||
app:showAsAction="ifRoom"
|
||||
/>
|
||||
|
||||
<item
|
||||
android:id="@+id/retry_icon"
|
||||
android:title="Retry"
|
||||
android:icon="@drawable/ic_refresh_white_24dp"
|
||||
android:orderInCategory="1"
|
||||
app:showAsAction="ifRoom"
|
||||
/>
|
||||
|
||||
<item
|
||||
android:id="@+id/cancel_icon"
|
||||
android:title="Cancel"
|
||||
android:icon="@android:drawable/ic_menu_close_clear_cancel"
|
||||
android:orderInCategory="1"
|
||||
app:showAsAction="ifRoom"
|
||||
/>
|
||||
</menu>
|
||||
|
|
@ -818,4 +818,6 @@ Upload your first media by tapping on the add button.</string>
|
|||
</plurals>
|
||||
<string name="multiple_files_depiction">Please remember that all images in a multi-upload get the same categories and depictions. If the images do not share depictions and categories, please perform several separate uploads.</string>
|
||||
<string name="multiple_files_depiction_header">Note about multi-uploads</string>
|
||||
<!-- TODO: Remove or change this placeholder text -->
|
||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -136,19 +136,6 @@ class ContributionViewHolderUnitTests {
|
|||
method.invoke(contributionViewHolder)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnPauseResumeButtonClickedCaseTrue() {
|
||||
contributionViewHolder.onPauseResumeButtonClicked()
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnPauseResumeButtonClickedCaseFalse() {
|
||||
bindind.pauseResumeButton.tag = ""
|
||||
contributionViewHolder.onPauseResumeButtonClicked()
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testWikipediaButtonClicked() {
|
||||
|
|
@ -161,18 +148,6 @@ class ContributionViewHolderUnitTests {
|
|||
contributionViewHolder.imageClicked()
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testDeleteUpload() {
|
||||
contributionViewHolder.deleteUpload()
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testRetryUpload() {
|
||||
contributionViewHolder.retryUpload()
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testChooseImageSource() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue