mirror of
				https://framagit.org/tom79/fedilab-tube
				synced 2025-06-05 21:09:11 +02:00 
			
		
		
		
	Change lib
This commit is contained in:
		| @@ -118,8 +118,8 @@ dependencies { | ||||
|     implementation "com.github.bumptech.glide:glide:4.11.0" | ||||
|     annotationProcessor "com.github.bumptech.glide:compiler:4.11.0" | ||||
|     implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" | ||||
|     implementation "net.gotev:uploadservice:3.5.2" | ||||
|     implementation "net.gotev:uploadservice-okhttp:3.5.2" | ||||
|     implementation "net.gotev:uploadservice:4.5.0" | ||||
|     implementation "net.gotev:uploadservice-okhttp:4.5.0" | ||||
|     implementation "com.google.code.gson:gson:2.8.6" | ||||
|     implementation 'androidx.media:media:1.2.0' | ||||
|     implementation 'com.github.ybq:Android-SpinKit:1.4.0' | ||||
|   | ||||
| @@ -157,13 +157,6 @@ | ||||
|         <service | ||||
|             android:name=".services.RetrieveInfoService" | ||||
|             android:exported="false" /> | ||||
|         <receiver | ||||
|             android:name=".services.PeertubeUploadReceiver" | ||||
|             android:exported="false"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="app.fedilab.fedilabtube.uploadservice.broadcast.status" /> | ||||
|             </intent-filter> | ||||
|         </receiver> | ||||
|  | ||||
|         <provider | ||||
|             android:name="androidx.work.impl.WorkManagerInitializer" | ||||
|   | ||||
| @@ -14,22 +14,30 @@ package app.fedilab.fedilabtube; | ||||
|  * You should have received a copy of the GNU General Public License along with TubeLab; if not, | ||||
|  * see <http://www.gnu.org/licenses>. */ | ||||
|  | ||||
| import android.app.NotificationChannel; | ||||
| import android.app.NotificationManager; | ||||
| import android.content.Context; | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Build; | ||||
|  | ||||
| import androidx.multidex.MultiDex; | ||||
| import androidx.multidex.MultiDexApplication; | ||||
| import androidx.work.Configuration; | ||||
| import androidx.work.WorkManager; | ||||
|  | ||||
| import net.gotev.uploadservice.UploadService; | ||||
| import net.gotev.uploadservice.UploadServiceConfig; | ||||
| import net.gotev.uploadservice.observer.request.GlobalRequestObserver; | ||||
|  | ||||
| import java.util.Objects; | ||||
|  | ||||
| import app.fedilab.fedilabtube.helper.Helper; | ||||
| import app.fedilab.fedilabtube.helper.ThemeHelper; | ||||
| import app.fedilab.fedilabtube.services.GlobalUploadObserver; | ||||
| import app.fedilab.fedilabtube.worker.WorkHelper; | ||||
|  | ||||
| public class FedilabTube extends MultiDexApplication { | ||||
|  | ||||
|     static String UPLOAD_CHANNEL_ID = "upload_info_peertube"; | ||||
|  | ||||
|     @Override | ||||
|     public void onCreate() { | ||||
| @@ -44,6 +52,10 @@ public class FedilabTube extends MultiDexApplication { | ||||
|         if (interval >= 15) { | ||||
|             WorkHelper.fetchNotifications(this, interval); | ||||
|         } | ||||
|         createNotificationChannel(); | ||||
|         UploadServiceConfig.initialize(FedilabTube.this, UPLOAD_CHANNEL_ID, true); | ||||
|  | ||||
|         new GlobalRequestObserver(this, new GlobalUploadObserver()); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @@ -52,8 +64,6 @@ public class FedilabTube extends MultiDexApplication { | ||||
|         super.attachBaseContext(base); | ||||
|  | ||||
|         MultiDex.install(FedilabTube.this); | ||||
|  | ||||
|         UploadService.NAMESPACE = BuildConfig.APPLICATION_ID; | ||||
|         SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); | ||||
|         int themePref = sharedpreferences.getInt(Helper.SET_THEME, Helper.DEFAULT_MODE); | ||||
|         ThemeHelper.switchTo(themePref); | ||||
| @@ -61,5 +71,13 @@ public class FedilabTube extends MultiDexApplication { | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     private void createNotificationChannel() { | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|             NotificationChannel channel = new NotificationChannel(UPLOAD_CHANNEL_ID, | ||||
|                     getString(R.string.notification_channel_name), | ||||
|                     NotificationManager.IMPORTANCE_LOW); | ||||
|             channel.setSound(null, null); | ||||
|             ((NotificationManager) Objects.requireNonNull(getSystemService(Context.NOTIFICATION_SERVICE))).createNotificationChannel(channel); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -21,10 +21,10 @@ import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.pm.PackageManager; | ||||
| import android.database.Cursor; | ||||
| import android.graphics.Bitmap; | ||||
| import android.graphics.Color; | ||||
| import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
| import android.provider.OpenableColumns; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.widget.AdapterView; | ||||
| @@ -38,20 +38,23 @@ import android.widget.Toast; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.core.app.ActivityCompat; | ||||
| import androidx.core.content.ContextCompat; | ||||
| import androidx.documentfile.provider.DocumentFile; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
|  | ||||
| import net.gotev.uploadservice.MultipartUploadRequest; | ||||
| import net.gotev.uploadservice.UploadNotificationAction; | ||||
| import net.gotev.uploadservice.UploadNotificationConfig; | ||||
|  | ||||
| import java.io.File; | ||||
| import net.gotev.uploadservice.data.UploadNotificationAction; | ||||
| import net.gotev.uploadservice.data.UploadNotificationConfig; | ||||
| import net.gotev.uploadservice.data.UploadNotificationStatusConfig; | ||||
| import net.gotev.uploadservice.extensions.ContextExtensionsKt; | ||||
| import net.gotev.uploadservice.protocols.multipart.MultipartUploadRequest; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Date; | ||||
| import java.util.HashMap; | ||||
| import java.util.Iterator; | ||||
| import java.util.LinkedHashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.UUID; | ||||
|  | ||||
| import app.fedilab.fedilabtube.client.APIResponse; | ||||
| import app.fedilab.fedilabtube.client.data.ChannelData; | ||||
| @@ -110,32 +113,17 @@ public class PeertubeUploadActivity extends AppCompatActivity { | ||||
|                 return; | ||||
|             } | ||||
|             set_upload_submit.setEnabled(true); | ||||
|  | ||||
|             uri = data.getData(); | ||||
|  | ||||
|             String uriString = uri.toString(); | ||||
|             File myFile = new File(uriString); | ||||
|             filename = null; | ||||
|             if (uriString.startsWith("content://")) { | ||||
|                 Cursor cursor = null; | ||||
|                 try { | ||||
|                     cursor = getContentResolver().query(uri, null, null, null, null); | ||||
|                     if (cursor != null && cursor.moveToFirst()) { | ||||
|                         filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); | ||||
|                     } | ||||
|                 } finally { | ||||
|                     assert cursor != null; | ||||
|                     cursor.close(); | ||||
|                 } | ||||
|             } else if (uriString.startsWith("file://")) { | ||||
|                 filename = myFile.getName(); | ||||
|             DocumentFile documentFile = DocumentFile.fromSingleUri(this, uri); | ||||
|             if (documentFile != null) { | ||||
|                 filename = documentFile.getName(); | ||||
|             } | ||||
|             if (filename == null) { | ||||
|                 filename = new Date().toString(); | ||||
|             } | ||||
|             set_upload_file_name.setVisibility(View.VISIBLE); | ||||
|             set_upload_file_name.setText(filename); | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -245,7 +233,7 @@ public class PeertubeUploadActivity extends AppCompatActivity { | ||||
|                         MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); | ||||
|                 return; | ||||
|             } | ||||
|             Intent intent = new Intent(Intent.ACTION_GET_CONTENT); | ||||
|             Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); | ||||
|             intent.addCategory(Intent.CATEGORY_OPENABLE); | ||||
|             intent.setType("*/*"); | ||||
|             String[] mimetypes = {"video/*"}; | ||||
| @@ -289,34 +277,19 @@ public class PeertubeUploadActivity extends AppCompatActivity { | ||||
|                 try { | ||||
|                     SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); | ||||
|                     String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null); | ||||
|                     UploadNotificationConfig uploadConfig = new UploadNotificationConfig(); | ||||
|                     Intent in = new Intent(PeertubeUploadActivity.this, PeertubeEditUploadActivity.class); | ||||
|                     PendingIntent clickIntent = PendingIntent.getActivity(PeertubeUploadActivity.this, 1, in, PendingIntent.FLAG_UPDATE_CURRENT); | ||||
|                     uploadConfig | ||||
|                             .setClearOnActionForAllStatuses(true); | ||||
|  | ||||
|  | ||||
|                     uploadConfig.getProgress().message = getString(R.string.uploading); | ||||
|                     uploadConfig.getCompleted().message = getString(R.string.upload_video_success); | ||||
|                     uploadConfig.getError().message = getString(R.string.toast_error); | ||||
|                     uploadConfig.getCancelled().message = getString(R.string.toast_cancelled); | ||||
|                     uploadConfig.getCompleted().actions.add(new UploadNotificationAction(R.drawable.ic_baseline_check_24, getString(R.string.video_uploaded_action), clickIntent)); | ||||
|  | ||||
|                     if (video_title != null && video_title.getText() != null && video_title.getText().toString().trim().length() > 0) { | ||||
|                         filename = video_title.getText().toString().trim(); | ||||
|                     } | ||||
|                     String uploadId = UUID.randomUUID().toString(); | ||||
|                     new MultipartUploadRequest(PeertubeUploadActivity.this, uploadId, "https://" + Helper.getLiveInstance(PeertubeUploadActivity.this) + "/api/v1/videos/upload") | ||||
|                             .addFileToUpload(uri.toString().replace("file://", ""), "videofile") | ||||
|                             .addHeader("Authorization", "Bearer " + token) | ||||
|                             .setNotificationConfig(uploadConfig) | ||||
|                             .addParameter("name", filename) | ||||
|                             .addParameter("channelId", idChannel) | ||||
|                     new MultipartUploadRequest(PeertubeUploadActivity.this, "https://" + Helper.getLiveInstance(PeertubeUploadActivity.this) + "/api/v1/videos/upload") | ||||
|                             .setMethod("POST") | ||||
|                             .setBearerAuth(token) | ||||
|                             .addHeader("User-Agent", getString(R.string.app_name) + "/" + BuildConfig.VERSION_NAME) | ||||
|                             .addParameter("privacy", String.valueOf(idPrivacy)) | ||||
|                             .addParameter("nsfw", "false") | ||||
|                             .addParameter("commentsEnabled", "true") | ||||
|                             .addParameter("downloadEnabled", "true") | ||||
|                             .addParameter("waitTranscoding", "true") | ||||
|                             .setMaxRetries(3) | ||||
|                             .addParameter("channelId", idChannel) | ||||
|                             .addFileToUpload(uri.toString(), "videofile", filename) | ||||
|                             .setNotificationConfig((context, uploadId) -> getNotificationConfig(uploadId)) | ||||
|                             .setMaxRetries(2) | ||||
|                             .startUpload(); | ||||
|                     finish(); | ||||
|                 } catch (Exception exc) { | ||||
| @@ -325,4 +298,83 @@ public class PeertubeUploadActivity extends AppCompatActivity { | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     UploadNotificationConfig getNotificationConfig(String uploadId) { | ||||
|         PendingIntent clickIntent = PendingIntent.getActivity( | ||||
|                 PeertubeUploadActivity.this, 1, new Intent(this, PeertubeUploadActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); | ||||
|  | ||||
|         final boolean autoClear = false; | ||||
|         final Bitmap largeIcon = null; | ||||
|         final boolean clearOnAction = true; | ||||
|         final boolean ringToneEnabled = true; | ||||
|         final ArrayList<UploadNotificationAction> noActions = new ArrayList<>(1); | ||||
|  | ||||
|         final UploadNotificationAction cancelAction = new UploadNotificationAction( | ||||
|                 R.drawable.ic_baseline_cancel_24, | ||||
|                 getString(R.string.cancel), | ||||
|                 ContextExtensionsKt.getCancelUploadIntent(this, uploadId) | ||||
|         ); | ||||
|  | ||||
|         final UploadNotificationAction successAction = new UploadNotificationAction( | ||||
|                 R.drawable.ic_baseline_cancel_24, | ||||
|                 getString(R.string.video_uploaded_action), | ||||
|                 clickIntent | ||||
|         ); | ||||
|  | ||||
|         final ArrayList<UploadNotificationAction> progressActions = new ArrayList<>(1); | ||||
|         progressActions.add(cancelAction); | ||||
|  | ||||
|         UploadNotificationStatusConfig progress = new UploadNotificationStatusConfig( | ||||
|                 getString(R.string.app_name), | ||||
|                 getString(R.string.uploading), | ||||
|                 R.drawable.ic_baseline_cloud_upload_24, | ||||
|                 Color.BLUE, | ||||
|                 largeIcon, | ||||
|                 clickIntent, | ||||
|                 progressActions, | ||||
|                 clearOnAction, | ||||
|                 autoClear | ||||
|         ); | ||||
|  | ||||
|         final ArrayList<UploadNotificationAction> successActions = new ArrayList<>(1); | ||||
|         progressActions.add(successAction); | ||||
|  | ||||
|         UploadNotificationStatusConfig success = new UploadNotificationStatusConfig( | ||||
|                 getString(R.string.app_name), | ||||
|                 getString(R.string.upload_video_success), | ||||
|                 R.drawable.ic_baseline_check_24, | ||||
|                 Color.GREEN, | ||||
|                 largeIcon, | ||||
|                 clickIntent, | ||||
|                 successActions, | ||||
|                 clearOnAction, | ||||
|                 autoClear | ||||
|         ); | ||||
|  | ||||
|  | ||||
|         UploadNotificationStatusConfig error = new UploadNotificationStatusConfig( | ||||
|                 getString(R.string.app_name), | ||||
|                 getString(R.string.toast_error), | ||||
|                 R.drawable.ic_baseline_error_24, | ||||
|                 Color.RED, | ||||
|                 largeIcon, | ||||
|                 clickIntent, | ||||
|                 noActions, | ||||
|                 clearOnAction, | ||||
|                 autoClear | ||||
|         ); | ||||
|  | ||||
|         UploadNotificationStatusConfig cancelled = new UploadNotificationStatusConfig( | ||||
|                 getString(R.string.app_name), | ||||
|                 getString(R.string.toast_cancelled), | ||||
|                 R.drawable.ic_baseline_cancel_24, | ||||
|                 Color.YELLOW, | ||||
|                 largeIcon, | ||||
|                 clickIntent, | ||||
|                 noActions, | ||||
|                 clearOnAction | ||||
|         ); | ||||
|  | ||||
|         return new UploadNotificationConfig(FedilabTube.UPLOAD_CHANNEL_ID, ringToneEnabled, progress, success, error, cancelled); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -130,7 +130,6 @@ public class Helper { | ||||
|     public static final String APP_PREFS = "app_prefs"; | ||||
|  | ||||
|     public static final int VIDEOS_PER_PAGE = 10; | ||||
|     public static final String INTENT_ADD_UPLOADED_MEDIA = "intent_add_uploaded_media"; | ||||
|     public static final String RECEIVE_ACTION = "receive_action"; | ||||
|     public static final String SET_UNFOLLOW_VALIDATION = "set_unfollow_validation"; | ||||
|     //List of available academies | ||||
|   | ||||
| @@ -0,0 +1,67 @@ | ||||
| package app.fedilab.fedilabtube.services; | ||||
| /* Copyright 2020 Thomas Schneider | ||||
|  * | ||||
|  * This file is a part of TubeLab | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify it under the terms of the | ||||
|  * GNU General Public License as published by the Free Software Foundation; either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even | ||||
|  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||||
|  * Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along with TubeLab; if not, | ||||
|  * see <http://www.gnu.org/licenses>. */ | ||||
|  | ||||
| import android.annotation.SuppressLint; | ||||
| import android.content.Context; | ||||
| import android.content.SharedPreferences; | ||||
|  | ||||
| import net.gotev.uploadservice.data.UploadInfo; | ||||
| import net.gotev.uploadservice.network.ServerResponse; | ||||
| import net.gotev.uploadservice.observer.request.RequestObserverDelegate; | ||||
|  | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
|  | ||||
| import app.fedilab.fedilabtube.helper.Helper; | ||||
|  | ||||
| public class GlobalUploadObserver implements RequestObserverDelegate { | ||||
|  | ||||
|     @Override | ||||
|     public void onCompleted(@NotNull Context context, @NotNull UploadInfo uploadInfo) { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onCompletedWhileNotObserving() { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onError(@NotNull Context context, @NotNull UploadInfo uploadInfo, @NotNull Throwable throwable) { | ||||
|         throwable.printStackTrace(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onProgress(@NotNull Context context, @NotNull UploadInfo uploadInfo) { | ||||
|     } | ||||
|  | ||||
|     @SuppressLint("ApplySharedPref") | ||||
|     @Override | ||||
|     public void onSuccess(@NotNull Context context, @NotNull UploadInfo uploadInfo, @NotNull ServerResponse serverResponse) { | ||||
|         try { | ||||
|             JSONObject response = new JSONObject(serverResponse.getBodyString()); | ||||
|  | ||||
|             if (response.has("video")) { | ||||
|                 String videoUuid = response.getJSONObject("video").getString("uuid"); | ||||
|                 SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); | ||||
|                 SharedPreferences.Editor editor = sharedpreferences.edit(); | ||||
|                 editor.putString(Helper.VIDEO_ID, videoUuid); | ||||
|                 editor.commit(); | ||||
|             } | ||||
|         } catch (JSONException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,77 +0,0 @@ | ||||
| package app.fedilab.fedilabtube.services; | ||||
| /* Copyright 2020 Thomas Schneider | ||||
|  * | ||||
|  * This file is a part of TubeLab | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify it under the terms of the | ||||
|  * GNU General Public License as published by the Free Software Foundation; either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even | ||||
|  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||||
|  * Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along with TubeLab; if not, | ||||
|  * see <http://www.gnu.org/licenses>. */ | ||||
|  | ||||
| import android.annotation.SuppressLint; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
|  | ||||
| import androidx.localbroadcastmanager.content.LocalBroadcastManager; | ||||
|  | ||||
| import net.gotev.uploadservice.ServerResponse; | ||||
| import net.gotev.uploadservice.UploadInfo; | ||||
| import net.gotev.uploadservice.UploadServiceBroadcastReceiver; | ||||
|  | ||||
| import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
|  | ||||
| import app.fedilab.fedilabtube.helper.Helper; | ||||
|  | ||||
|  | ||||
| public class PeertubeUploadReceiver extends UploadServiceBroadcastReceiver { | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public void onProgress(Context context, UploadInfo uploadInfo) { | ||||
|         // your code here | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onError(Context context, UploadInfo uploadInfo, ServerResponse serverResponse, | ||||
|                         Exception exception) { | ||||
|     } | ||||
|  | ||||
|     @SuppressLint("ApplySharedPref") | ||||
|     @Override | ||||
|     public void onCompleted(Context context, UploadInfo uploadInfo, ServerResponse serverResponse) { | ||||
|         try { | ||||
|             JSONObject response = new JSONObject(serverResponse.getBodyAsString()); | ||||
|  | ||||
|             if (!response.has("video")) { //IT's not from Peertube | ||||
|                 ArrayList<String> file = uploadInfo.getSuccessfullyUploadedFiles(); | ||||
|                 Intent addMedia = new Intent(Helper.INTENT_ADD_UPLOADED_MEDIA); | ||||
|                 addMedia.putExtra("response", serverResponse.getBodyAsString()); | ||||
|                 addMedia.putStringArrayListExtra("uploadInfo", file); | ||||
|                 LocalBroadcastManager.getInstance(context).sendBroadcast(addMedia); | ||||
|             } else { | ||||
|                 String videoID = response.getJSONObject("video").get("id").toString(); | ||||
|                 SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); | ||||
|                 SharedPreferences.Editor editor = sharedpreferences.edit(); | ||||
|                 editor.putString(Helper.VIDEO_ID, videoID); | ||||
|                 editor.apply(); | ||||
|             } | ||||
|         } catch (JSONException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onCancelled(Context context, UploadInfo uploadInfo) { | ||||
|         // your code here | ||||
|     } | ||||
| } | ||||
							
								
								
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_cancel_24.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_cancel_24.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:width="24dp" | ||||
|     android:height="24dp" | ||||
|     android:tint="?attr/colorControlNormal" | ||||
|     android:viewportWidth="24" | ||||
|     android:viewportHeight="24"> | ||||
|     <path | ||||
|         android:fillColor="@android:color/white" | ||||
|         android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z" /> | ||||
| </vector> | ||||
| @@ -1,8 +1,8 @@ | ||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:width="24dp" | ||||
|     android:height="24dp" | ||||
|     android:tint="?attr/colorControlNormal" | ||||
|     android:viewportWidth="24" | ||||
|     android:tint="?attr/colorControlNormal" | ||||
|     android:viewportHeight="24"> | ||||
|     <path | ||||
|         android:fillColor="@android:color/white" | ||||
|   | ||||
							
								
								
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_error_24.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_error_24.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:width="24dp" | ||||
|     android:height="24dp" | ||||
|     android:tint="?attr/colorControlNormal" | ||||
|     android:viewportWidth="24" | ||||
|     android:viewportHeight="24"> | ||||
|     <path | ||||
|         android:fillColor="@android:color/white" | ||||
|         android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z" /> | ||||
| </vector> | ||||
		Reference in New Issue
	
	Block a user