mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-23 13:35:33 +03:00
Merge pull request #1542 from nextcloud/feature/306/directCamUpload
Adding upload from camera action
This commit is contained in:
commit
39d0052fb4
54 changed files with 1602 additions and 130 deletions
|
@ -187,6 +187,12 @@ dependencies {
|
|||
ktlint "com.pinterest:ktlint:0.43.0"
|
||||
implementation 'org.conscrypt:conscrypt-android:2.5.2'
|
||||
|
||||
implementation 'androidx.camera:camera-core:1.0.2'
|
||||
implementation 'androidx.camera:camera-camera2:1.0.2'
|
||||
implementation 'androidx.camera:camera-lifecycle:1.0.2'
|
||||
implementation 'androidx.camera:camera-view:1.0.0-alpha28'
|
||||
implementation "androidx.exifinterface:exifinterface:1.3.3"
|
||||
|
||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||
|
||||
implementation 'androidx.biometric:biometric:1.1.0'
|
||||
|
|
|
@ -160,6 +160,11 @@
|
|||
android:configChanges="orientation|keyboardHidden|screenSize">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".activities.TakePhotoActivity"
|
||||
android:theme="@style/TakePhotoTheme"
|
||||
android:windowSoftInputMode="stateHidden" />
|
||||
|
||||
<receiver android:name=".receivers.PackageReplacedReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
|
|
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Andy Scherzinger
|
||||
* @author Stefan Niedermann
|
||||
* Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
* Copyright (C) 2021 Stefan Niedermann <info@niedermann.it>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.Size;
|
||||
import android.view.OrientationEventListener;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.nextcloud.talk.R;
|
||||
import com.nextcloud.talk.databinding.ActivityTakePictureBinding;
|
||||
import com.nextcloud.talk.models.TakePictureViewModel;
|
||||
import com.nextcloud.talk.utils.BitmapShrinker;
|
||||
import com.nextcloud.talk.utils.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.camera.core.AspectRatio;
|
||||
import androidx.camera.core.Camera;
|
||||
import androidx.camera.core.ImageCapture;
|
||||
import androidx.camera.core.ImageCaptureException;
|
||||
import androidx.camera.core.Preview;
|
||||
import androidx.camera.lifecycle.ProcessCameraProvider;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.exifinterface.media.ExifInterface;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
public class TakePhotoActivity extends AppCompatActivity {
|
||||
|
||||
private static final String TAG = TakePhotoActivity.class.getSimpleName();
|
||||
|
||||
private static final float MAX_SCALE = 6.0f;
|
||||
private static final float MEDIUM_SCALE = 2.45f;
|
||||
|
||||
private ActivityTakePictureBinding binding;
|
||||
private TakePictureViewModel viewModel;
|
||||
|
||||
private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
|
||||
private OrientationEventListener orientationEventListener;
|
||||
|
||||
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss", Locale.ROOT);
|
||||
|
||||
private Camera camera;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
binding = ActivityTakePictureBinding.inflate(getLayoutInflater());
|
||||
viewModel = new ViewModelProvider(this).get(TakePictureViewModel.class);
|
||||
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
|
||||
cameraProviderFuture.addListener(() -> {
|
||||
try {
|
||||
final ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
|
||||
|
||||
camera = cameraProvider.bindToLifecycle(
|
||||
this,
|
||||
viewModel.getCameraSelector(),
|
||||
getImageCapture(
|
||||
viewModel.isCropEnabled().getValue(), viewModel.isLowResolutionEnabled().getValue()),
|
||||
getPreview(viewModel.isCropEnabled().getValue()));
|
||||
|
||||
viewModel.getTorchToggleButtonImageResource()
|
||||
.observe(
|
||||
this,
|
||||
res -> binding.toggleTorch.setIcon(ContextCompat.getDrawable(this, res)));
|
||||
viewModel.isTorchEnabled()
|
||||
.observe(
|
||||
this,
|
||||
enabled -> camera.getCameraControl().enableTorch(viewModel.isTorchEnabled().getValue()));
|
||||
binding.toggleTorch.setOnClickListener((v) -> viewModel.toggleTorchEnabled());
|
||||
|
||||
viewModel.getCropToggleButtonImageResource()
|
||||
.observe(
|
||||
this,
|
||||
res -> binding.toggleCrop.setIcon(ContextCompat.getDrawable(this, res)));
|
||||
viewModel.isCropEnabled()
|
||||
.observe(
|
||||
this,
|
||||
enabled -> {
|
||||
cameraProvider.unbindAll();
|
||||
camera = cameraProvider.bindToLifecycle(
|
||||
this,
|
||||
viewModel.getCameraSelector(),
|
||||
getImageCapture(
|
||||
viewModel.isCropEnabled().getValue(), viewModel.isLowResolutionEnabled().getValue()),
|
||||
getPreview(viewModel.isCropEnabled().getValue()));
|
||||
camera.getCameraControl().enableTorch(viewModel.isTorchEnabled().getValue());
|
||||
});
|
||||
binding.toggleCrop.setOnClickListener((v) -> viewModel.toggleCropEnabled());
|
||||
|
||||
viewModel.getLowResolutionToggleButtonImageResource()
|
||||
.observe(
|
||||
this,
|
||||
res -> binding.toggleLowres.setIcon(ContextCompat.getDrawable(this, res)));
|
||||
viewModel.isLowResolutionEnabled()
|
||||
.observe(
|
||||
this,
|
||||
enabled -> {
|
||||
cameraProvider.unbindAll();
|
||||
camera = cameraProvider.bindToLifecycle(
|
||||
this,
|
||||
viewModel.getCameraSelector(),
|
||||
getImageCapture(
|
||||
viewModel.isCropEnabled().getValue(), viewModel.isLowResolutionEnabled().getValue()),
|
||||
getPreview(viewModel.isCropEnabled().getValue()));
|
||||
camera.getCameraControl().enableTorch(viewModel.isTorchEnabled().getValue());
|
||||
});
|
||||
binding.toggleLowres.setOnClickListener((v) -> viewModel.toggleLowResolutionEnabled());
|
||||
|
||||
binding.switchCamera.setOnClickListener((v) -> {
|
||||
viewModel.toggleCameraSelector();
|
||||
cameraProvider.unbindAll();
|
||||
camera = cameraProvider.bindToLifecycle(
|
||||
this,
|
||||
viewModel.getCameraSelector(),
|
||||
getImageCapture(
|
||||
viewModel.isCropEnabled().getValue(), viewModel.isLowResolutionEnabled().getValue()),
|
||||
getPreview(viewModel.isCropEnabled().getValue()));
|
||||
});
|
||||
binding.retake.setOnClickListener((v) -> {
|
||||
Uri uri = (Uri) binding.photoPreview.getTag();
|
||||
File photoFile = new File(uri.getPath());
|
||||
if (!photoFile.delete()) {
|
||||
Log.w(TAG, "Error deleting temp camera image");
|
||||
}
|
||||
binding.takePhoto.setEnabled(true);
|
||||
binding.photoPreview.setTag(null);
|
||||
showCameraElements();
|
||||
});
|
||||
binding.send.setOnClickListener((v) -> {
|
||||
Uri uri = (Uri) binding.photoPreview.getTag();
|
||||
setResult(RESULT_OK, new Intent().setDataAndType(uri, "image/jpeg"));
|
||||
binding.photoPreview.setTag(null);
|
||||
finish();
|
||||
});
|
||||
|
||||
ScaleGestureDetector mDetector =
|
||||
new ScaleGestureDetector(this, new ScaleGestureDetector.SimpleOnScaleGestureListener(){
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector detector){
|
||||
float ratio = camera.getCameraInfo().getZoomState().getValue().getZoomRatio();
|
||||
float delta = detector.getScaleFactor();
|
||||
camera.getCameraControl().setZoomRatio(ratio * delta);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
binding.preview.setOnTouchListener((v, event) -> {
|
||||
v.performClick();
|
||||
mDetector.onTouchEvent(event);
|
||||
return true;
|
||||
});
|
||||
|
||||
// Enable enlarging the image more than default 3x maximumScale.
|
||||
// Medium scale adapted to make double-tap behaviour more consistent.
|
||||
binding.photoPreview.setMaximumScale(MAX_SCALE);
|
||||
binding.photoPreview.setMediumScale(MEDIUM_SCALE);
|
||||
} catch (IllegalArgumentException | ExecutionException | InterruptedException e) {
|
||||
Log.e(TAG, "Error taking picture", e);
|
||||
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
}
|
||||
}, ContextCompat.getMainExecutor(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
Uri uri = (Uri) binding.photoPreview.getTag();
|
||||
|
||||
if (uri != null) {
|
||||
File photoFile = new File(uri.getPath());
|
||||
if (!photoFile.delete()) {
|
||||
Log.w(TAG, "Error deleting temp camera image");
|
||||
}
|
||||
binding.photoPreview.setTag(null);
|
||||
}
|
||||
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
private void showCameraElements() {
|
||||
binding.send.setVisibility(View.GONE);
|
||||
binding.retake.setVisibility(View.GONE);
|
||||
binding.photoPreview.setVisibility(View.INVISIBLE);
|
||||
|
||||
binding.preview.setVisibility(View.VISIBLE);
|
||||
binding.takePhoto.setVisibility(View.VISIBLE);
|
||||
binding.switchCamera.setVisibility(View.VISIBLE);
|
||||
binding.toggleTorch.setVisibility(View.VISIBLE);
|
||||
binding.toggleCrop.setVisibility(View.VISIBLE);
|
||||
binding.toggleLowres.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void showPictureProcessingElements() {
|
||||
binding.preview.setVisibility(View.INVISIBLE);
|
||||
binding.takePhoto.setVisibility(View.GONE);
|
||||
binding.switchCamera.setVisibility(View.GONE);
|
||||
binding.toggleTorch.setVisibility(View.GONE);
|
||||
binding.toggleCrop.setVisibility(View.GONE);
|
||||
binding.toggleLowres.setVisibility(View.GONE);
|
||||
|
||||
binding.send.setVisibility(View.VISIBLE);
|
||||
binding.retake.setVisibility(View.VISIBLE);
|
||||
binding.photoPreview.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private ImageCapture getImageCapture(Boolean crop, Boolean lowres) {
|
||||
final ImageCapture imageCapture;
|
||||
if (lowres) imageCapture = new ImageCapture.Builder()
|
||||
.setTargetResolution(new Size(crop ? 1080 : 1440, 1920)).build();
|
||||
else imageCapture = new ImageCapture.Builder()
|
||||
.setTargetAspectRatio(crop ? AspectRatio.RATIO_16_9 : AspectRatio.RATIO_4_3).build();
|
||||
|
||||
orientationEventListener = new OrientationEventListener(this) {
|
||||
@Override
|
||||
public void onOrientationChanged(int orientation) {
|
||||
int rotation;
|
||||
|
||||
// Monitors orientation values to determine the target rotation value
|
||||
if (orientation >= 45 && orientation < 135) {
|
||||
rotation = Surface.ROTATION_270;
|
||||
} else if (orientation >= 135 && orientation < 225) {
|
||||
rotation = Surface.ROTATION_180;
|
||||
} else if (orientation >= 225 && orientation < 315) {
|
||||
rotation = Surface.ROTATION_90;
|
||||
} else {
|
||||
rotation = Surface.ROTATION_0;
|
||||
}
|
||||
|
||||
imageCapture.setTargetRotation(rotation);
|
||||
}
|
||||
};
|
||||
orientationEventListener.enable();
|
||||
|
||||
binding.takePhoto.setOnClickListener((v) -> {
|
||||
binding.takePhoto.setEnabled(false);
|
||||
final String photoFileName = dateFormat.format(new Date()) + ".jpg";
|
||||
try {
|
||||
final File photoFile = FileUtils.getTempCacheFile(this, "photos/" + photoFileName);
|
||||
final ImageCapture.OutputFileOptions options =
|
||||
new ImageCapture.OutputFileOptions.Builder(photoFile).build();
|
||||
imageCapture.takePicture(
|
||||
options,
|
||||
ContextCompat.getMainExecutor(this),
|
||||
new ImageCapture.OnImageSavedCallback() {
|
||||
|
||||
@Override
|
||||
public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
|
||||
setPreviewImage(photoFile);
|
||||
showPictureProcessingElements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull ImageCaptureException e) {
|
||||
Log.e(TAG, "Error", e);
|
||||
|
||||
if (!photoFile.delete()) {
|
||||
Log.w(TAG, "Deleting picture failed");
|
||||
}
|
||||
binding.takePhoto.setEnabled(true);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(this, R.string.take_photo_error_deleting_picture, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
return imageCapture;
|
||||
}
|
||||
|
||||
private void setPreviewImage(File photoFile) {
|
||||
final Uri savedUri = Uri.fromFile(photoFile);
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
|
||||
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
|
||||
int doubleScreenWidth = displayMetrics.widthPixels * 2;
|
||||
int doubleScreenHeight = displayMetrics.heightPixels * 2;
|
||||
|
||||
Bitmap bitmap = BitmapShrinker.shrinkBitmap(photoFile.getAbsolutePath(),
|
||||
doubleScreenWidth,
|
||||
doubleScreenHeight);
|
||||
|
||||
binding.photoPreview.setImageBitmap(bitmap);
|
||||
binding.photoPreview.setTag(savedUri);
|
||||
viewModel.disableTorchIfEnabled();
|
||||
}
|
||||
|
||||
public int getImageOrientation(File imageFile) {
|
||||
int rotate = 0;
|
||||
try {
|
||||
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
|
||||
int orientation = exif.getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_NORMAL);
|
||||
|
||||
switch (orientation) {
|
||||
case ExifInterface.ORIENTATION_ROTATE_270:
|
||||
rotate = 270;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_180:
|
||||
rotate = 180;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_90:
|
||||
rotate = 90;
|
||||
break;
|
||||
default:
|
||||
rotate = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Log.i(TAG, "ImageOrientation - Exif orientation: " + orientation + " - " + "Rotate value: " + rotate);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Error calculation rotation value");
|
||||
}
|
||||
return rotate;
|
||||
}
|
||||
|
||||
private Preview getPreview(Boolean crop) {
|
||||
Preview preview = new Preview.Builder()
|
||||
.setTargetAspectRatio(crop ? AspectRatio.RATIO_16_9 : AspectRatio.RATIO_4_3).build();
|
||||
preview.setSurfaceProvider(binding.preview.getSurfaceProvider());
|
||||
|
||||
return preview;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
if (this.orientationEventListener != null) {
|
||||
this.orientationEventListener.disable();
|
||||
}
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (this.orientationEventListener != null) {
|
||||
this.orientationEventListener.enable();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle savedInstanceState) {
|
||||
if (binding.photoPreview.getTag() != null) {
|
||||
savedInstanceState.putString("Uri", ((Uri) binding.photoPreview.getTag()).getPath());
|
||||
}
|
||||
|
||||
super.onSaveInstanceState(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
|
||||
String uri = savedInstanceState.getString("Uri", null);
|
||||
|
||||
if (uri != null) {
|
||||
File photoFile = new File(uri);
|
||||
setPreviewImage(photoFile);
|
||||
showPictureProcessingElements();
|
||||
}
|
||||
}
|
||||
|
||||
public static Intent createIntent(@NonNull Context context) {
|
||||
return new Intent(context, TakePhotoActivity.class).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
}
|
||||
}
|
|
@ -281,7 +281,7 @@ public class AccountVerificationController extends BaseController {
|
|||
|
||||
private void storeProfile(String displayName, String userId) {
|
||||
userUtils.createOrUpdateUser(username, token,
|
||||
baseUrl, displayName, null, true,
|
||||
baseUrl, displayName, null, Boolean.TRUE,
|
||||
userId, null, null,
|
||||
appPreferences.getTemporaryClientCertAlias(), null)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
|
|
@ -96,6 +96,7 @@ import com.google.android.flexbox.FlexboxLayout
|
|||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.activities.CallActivity
|
||||
import com.nextcloud.talk.activities.MainActivity
|
||||
import com.nextcloud.talk.activities.TakePhotoActivity
|
||||
import com.nextcloud.talk.adapters.messages.IncomingLocationMessageViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.IncomingPreviewMessageViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.IncomingVoiceMessageViewHolder
|
||||
|
@ -990,6 +991,17 @@ class ChatController(args: Bundle) :
|
|||
}
|
||||
}
|
||||
|
||||
private fun isCameraPermissionGranted(): Boolean {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
return PermissionChecker.checkSelfPermission(
|
||||
context!!,
|
||||
Manifest.permission.CAMERA
|
||||
) == PermissionChecker.PERMISSION_GRANTED
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private fun startAudioRecording(file: String) {
|
||||
binding.messageInputView.audioRecordDuration.base = SystemClock.elapsedRealtime()
|
||||
binding.messageInputView.audioRecordDuration.start()
|
||||
|
@ -1079,6 +1091,15 @@ class ChatController(args: Bundle) :
|
|||
)
|
||||
}
|
||||
|
||||
private fun requestCameraPermissions() {
|
||||
requestPermissions(
|
||||
arrayOf(
|
||||
Manifest.permission.CAMERA
|
||||
),
|
||||
REQUEST_CAMERA_PERMISSION
|
||||
)
|
||||
}
|
||||
|
||||
private fun checkReadOnlyState() {
|
||||
if (currentConversation != null && isAlive()) {
|
||||
if (currentConversation?.shouldShowLobby(conversationUser) ?: false ||
|
||||
|
@ -1221,6 +1242,34 @@ class ChatController(args: Bundle) :
|
|||
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
||||
}
|
||||
}
|
||||
} else if (requestCode == REQUEST_CODE_PICK_CAMERA) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
try {
|
||||
checkNotNull(intent)
|
||||
filesToUpload.clear()
|
||||
run {
|
||||
checkNotNull(intent.data)
|
||||
intent.data.let {
|
||||
filesToUpload.add(intent.data.toString())
|
||||
}
|
||||
}
|
||||
require(filesToUpload.isNotEmpty())
|
||||
|
||||
if (UploadAndShareFilesWorker.isStoragePermissionGranted(context!!)) {
|
||||
uploadFiles(filesToUpload, false)
|
||||
} else {
|
||||
UploadAndShareFilesWorker.requestStoragePermission(this)
|
||||
}
|
||||
} catch (e: IllegalStateException) {
|
||||
Toast.makeText(context, context?.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG)
|
||||
.show()
|
||||
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
Toast.makeText(context, context?.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG)
|
||||
.show()
|
||||
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1246,6 +1295,15 @@ class ChatController(args: Bundle) :
|
|||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
} else if (requestCode == REQUEST_CAMERA_PERMISSION) {
|
||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d(TAG, "launch cam activity since permission for cam has been granted")
|
||||
startActivityForResult(TakePhotoActivity.createIntent(context!!), REQUEST_CODE_PICK_CAMERA)
|
||||
} else {
|
||||
Toast
|
||||
.makeText(context, context?.getString(R.string.take_photo_permission), Toast.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2542,6 +2600,14 @@ class ChatController(args: Bundle) :
|
|||
}
|
||||
}
|
||||
|
||||
fun sendPictureFromCamIntent() {
|
||||
if (!isCameraPermissionGranted()) {
|
||||
requestCameraPermissions()
|
||||
} else {
|
||||
startActivityForResult(TakePhotoActivity.createIntent(context!!), REQUEST_CODE_PICK_CAMERA)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "ChatController"
|
||||
private const val CONTENT_TYPE_SYSTEM_MESSAGE: Byte = 1
|
||||
|
@ -2556,6 +2622,8 @@ class ChatController(args: Bundle) :
|
|||
private const val AGE_THREHOLD_FOR_DELETE_MESSAGE: Int = 21600000 // (6 hours in millis = 6 * 3600 * 1000)
|
||||
private const val REQUEST_CODE_CHOOSE_FILE: Int = 555
|
||||
private const val REQUEST_RECORD_AUDIO_PERMISSION = 222
|
||||
private const val REQUEST_CAMERA_PERMISSION = 223
|
||||
private const val REQUEST_CODE_PICK_CAMERA: Int = 333
|
||||
private const val OBJECT_MESSAGE: String = "{object}"
|
||||
private const val MINIMUM_VOICE_RECORD_DURATION: Int = 1000
|
||||
private const val VOICE_RECORD_CANCEL_SLIDER_X: Int = -50
|
||||
|
|
|
@ -77,7 +77,6 @@ import com.nextcloud.talk.models.json.generic.GenericOverall;
|
|||
import com.nextcloud.talk.models.json.userprofile.UserProfileOverall;
|
||||
import com.nextcloud.talk.utils.ApiUtils;
|
||||
import com.nextcloud.talk.utils.DisplayUtils;
|
||||
import com.nextcloud.talk.utils.DoNotDisturbUtils;
|
||||
import com.nextcloud.talk.utils.LoggingUtils;
|
||||
import com.nextcloud.talk.utils.SecurityUtils;
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys;
|
||||
|
@ -132,8 +131,6 @@ public class SettingsController extends BaseController {
|
|||
private static final int ID_REMOVE_ACCOUNT_WARNING_DIALOG = 0;
|
||||
@BindView(R.id.settings_screen)
|
||||
MaterialPreferenceScreen settingsScreen;
|
||||
@BindView(R.id.settings_proxy_choice)
|
||||
MaterialChoicePreference proxyChoice;
|
||||
@BindView(R.id.settings_proxy_port_edit)
|
||||
MaterialEditTextPreference proxyPortEditText;
|
||||
@BindView(R.id.settings_licence)
|
||||
|
|
|
@ -96,7 +96,7 @@ public class SwitchAccountController extends BaseController {
|
|||
UserEntity userEntity = ((AdvancedUserItem) userItems.get(position)).getEntity();
|
||||
userUtils.createOrUpdateUser(null,
|
||||
null, null, null,
|
||||
null, true, null, userEntity.getId(), null, null, null)
|
||||
null, Boolean.TRUE, null, userEntity.getId(), null, null, null)
|
||||
.subscribe(new Observer<UserEntity>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
|
|
|
@ -398,7 +398,7 @@ public class WebViewLoginController extends BaseController {
|
|||
if (isPasswordUpdate) {
|
||||
if (currentUser != null) {
|
||||
userQueryDisposable = userUtils.createOrUpdateUser(null, loginData.getToken(),
|
||||
null, null, "", true,
|
||||
null, null, "", Boolean.TRUE,
|
||||
null, currentUser.getId(), null, appPreferences.getTemporaryClientCertAlias(), null)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
|
|
@ -21,21 +21,14 @@
|
|||
package com.nextcloud.talk.controllers.bottomsheet;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.work.Data;
|
||||
import androidx.work.OneTimeWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
import autodagger.AutoInjector;
|
||||
import butterknife.BindView;
|
||||
|
||||
import com.bluelinelabs.conductor.RouterTransaction;
|
||||
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
|
||||
import com.kennyc.bottomsheet.adapters.AppAdapter;
|
||||
|
@ -55,17 +48,30 @@ import com.nextcloud.talk.utils.DisplayUtils;
|
|||
import com.nextcloud.talk.utils.ShareUtils;
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys;
|
||||
import com.nextcloud.talk.utils.database.user.UserUtils;
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter;
|
||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager;
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.parceler.Parcel;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.work.Data;
|
||||
import androidx.work.OneTimeWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
import autodagger.AutoInjector;
|
||||
import butterknife.BindView;
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter;
|
||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager;
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication.class)
|
||||
public class CallMenuController extends BaseController implements FlexibleAdapter.OnItemClickListener {
|
||||
@BindView(R.id.recycler_view)
|
||||
|
@ -77,6 +83,9 @@ public class CallMenuController extends BaseController implements FlexibleAdapte
|
|||
@Inject
|
||||
UserUtils userUtils;
|
||||
|
||||
@Inject
|
||||
Context context;
|
||||
|
||||
private Conversation conversation;
|
||||
private List<AbstractFlexibleItem> menuItems;
|
||||
private FlexibleAdapter<AbstractFlexibleItem> adapter;
|
||||
|
@ -104,6 +113,7 @@ public class CallMenuController extends BaseController implements FlexibleAdapte
|
|||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) {
|
||||
return inflater.inflate(R.layout.controller_call_menu, container, false);
|
||||
}
|
||||
|
@ -153,45 +163,57 @@ public class CallMenuController extends BaseController implements FlexibleAdapte
|
|||
if (conversation.isFavorite()) {
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_remove_from_favorites), 97, DisplayUtils.getTintedDrawable(getResources(), R.drawable.ic_star_border_black_24dp, R.color.grey_600)));
|
||||
} else if (CapabilitiesUtil.hasSpreedFeatureCapability(currentUser, "favorites")) {
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_add_to_favorites)
|
||||
, 98, DisplayUtils.getTintedDrawable(getResources(), R.drawable.ic_star_black_24dp, R.color.grey_600)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_add_to_favorites),
|
||||
98,
|
||||
DisplayUtils.getTintedDrawable(getResources(),
|
||||
R.drawable.ic_star_black_24dp,
|
||||
R.color.grey_600)));
|
||||
}
|
||||
|
||||
if (conversation.isNameEditable(currentUser)) {
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_rename), 2, getResources().getDrawable(R.drawable
|
||||
.ic_pencil_grey600_24dp)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_rename),
|
||||
2,
|
||||
ContextCompat.getDrawable(context,
|
||||
R.drawable.ic_pencil_grey600_24dp)));
|
||||
}
|
||||
|
||||
if (conversation.canModerate(currentUser)) {
|
||||
if (!conversation.isPublic()) {
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_make_call_public), 3, getResources().getDrawable(R.drawable
|
||||
.ic_link_grey600_24px)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_make_call_public),
|
||||
3, ContextCompat.getDrawable(context,
|
||||
R.drawable.ic_link_grey600_24px)));
|
||||
} else {
|
||||
if (conversation.isHasPassword()) {
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_change_password), 4, getResources().getDrawable(R.drawable
|
||||
.ic_lock_grey600_24px)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_clear_password), 5, getResources().getDrawable(R.drawable
|
||||
.ic_lock_open_grey600_24dp)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_change_password),
|
||||
4, ContextCompat.getDrawable(context,
|
||||
R.drawable.ic_lock_grey600_24px)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_clear_password),
|
||||
5,
|
||||
ContextCompat.getDrawable(context,
|
||||
R.drawable.ic_lock_open_grey600_24dp)));
|
||||
} else {
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_set_password), 6, getResources().getDrawable(R.drawable
|
||||
.ic_lock_plus_grey600_24dp)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_set_password),
|
||||
6, ContextCompat.getDrawable(context,
|
||||
R.drawable.ic_lock_plus_grey600_24dp)));
|
||||
}
|
||||
}
|
||||
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_delete_call), 9, getResources().getDrawable(R.drawable
|
||||
.ic_delete_grey600_24dp)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_delete_call),
|
||||
9, ContextCompat.getDrawable(context,
|
||||
R.drawable.ic_delete_grey600_24dp)));
|
||||
}
|
||||
|
||||
if (conversation.isPublic()) {
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_share_link), 7, getResources().getDrawable(R.drawable
|
||||
.ic_link_grey600_24px)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_share_link),
|
||||
7, ContextCompat.getDrawable(context,
|
||||
R.drawable.ic_link_grey600_24px)));
|
||||
if (conversation.canModerate(currentUser)) {
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_make_call_private), 8, getResources().getDrawable(R.drawable
|
||||
.ic_group_grey600_24px)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_make_call_private),
|
||||
8, ContextCompat.getDrawable(context,
|
||||
R.drawable.ic_group_grey600_24px)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (conversation.canLeave(currentUser)) {
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_leave), 1,
|
||||
DisplayUtils.getTintedDrawable(getResources(),
|
||||
|
@ -202,8 +224,10 @@ public class CallMenuController extends BaseController implements FlexibleAdapte
|
|||
prepareIntent();
|
||||
List<AppAdapter.AppInfo> appInfoList = ShareUtils.getShareApps(getActivity(), shareIntent, null,
|
||||
null);
|
||||
menuItems.add(new AppItem(getResources().getString(R.string.nc_share_link_via), "", "",
|
||||
getResources().getDrawable(R.drawable.ic_link_grey600_24px)));
|
||||
menuItems.add(new AppItem(getResources().getString(R.string.nc_share_link_via),
|
||||
"",
|
||||
"",
|
||||
ContextCompat.getDrawable(context, R.drawable.ic_link_grey600_24px)));
|
||||
if (appInfoList != null) {
|
||||
for (AppAdapter.AppInfo appInfo : appInfoList) {
|
||||
menuItems.add(new AppItem(appInfo.title, appInfo.packageName, appInfo.name, appInfo.drawable));
|
||||
|
@ -211,8 +235,12 @@ public class CallMenuController extends BaseController implements FlexibleAdapte
|
|||
}
|
||||
} else {
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_start_conversation), 0, null));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_new_conversation), 1, getResources().getDrawable(R.drawable.ic_add_grey600_24px)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_join_via_link), 2, getResources().getDrawable(R.drawable.ic_link_grey600_24px)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_new_conversation),
|
||||
1, ContextCompat.getDrawable(context,
|
||||
R.drawable.ic_add_grey600_24px)));
|
||||
menuItems.add(new MenuItem(getResources().getString(R.string.nc_join_via_link),
|
||||
2, ContextCompat.getDrawable(context,
|
||||
R.drawable.ic_link_grey600_24px)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Andy Scherzinger
|
||||
* @author Stefan Niedermann
|
||||
* Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
* Copyright (C) 2021 Stefan Niedermann <info@niedermann.it>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.models;
|
||||
|
||||
import com.nextcloud.talk.R;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.camera.core.CameraSelector;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.Transformations;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import static androidx.camera.core.CameraSelector.DEFAULT_BACK_CAMERA;
|
||||
import static androidx.camera.core.CameraSelector.DEFAULT_FRONT_CAMERA;
|
||||
|
||||
public class TakePictureViewModel extends ViewModel {
|
||||
|
||||
@NonNull
|
||||
private CameraSelector cameraSelector = DEFAULT_BACK_CAMERA;
|
||||
|
||||
@NonNull
|
||||
private final MutableLiveData<Boolean> torchEnabled = new MutableLiveData<>(Boolean.FALSE);
|
||||
|
||||
@NonNull
|
||||
private final MutableLiveData<Boolean> lowResolutionEnabled = new MutableLiveData<>(Boolean.FALSE);
|
||||
|
||||
@NonNull
|
||||
private final MutableLiveData<Boolean> cropEnabled = new MutableLiveData<>(Boolean.FALSE);
|
||||
|
||||
@NonNull
|
||||
public CameraSelector getCameraSelector() {
|
||||
return this.cameraSelector;
|
||||
}
|
||||
|
||||
public void toggleCameraSelector() {
|
||||
if (this.cameraSelector == DEFAULT_BACK_CAMERA) {
|
||||
this.cameraSelector = DEFAULT_FRONT_CAMERA;
|
||||
if (this.torchEnabled.getValue()) {
|
||||
toggleTorchEnabled();
|
||||
}
|
||||
} else {
|
||||
this.cameraSelector = DEFAULT_BACK_CAMERA;
|
||||
}
|
||||
}
|
||||
|
||||
public void disableTorchIfEnabled() {
|
||||
if (this.torchEnabled.getValue()) {
|
||||
toggleTorchEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleTorchEnabled() {
|
||||
//noinspection ConstantConditions
|
||||
this.torchEnabled.postValue(!this.torchEnabled.getValue());
|
||||
}
|
||||
|
||||
public void toggleLowResolutionEnabled() {
|
||||
//noinspection ConstantConditions
|
||||
this.lowResolutionEnabled.postValue(!this.lowResolutionEnabled.getValue());
|
||||
}
|
||||
|
||||
public void toggleCropEnabled() {
|
||||
//noinspection ConstantConditions
|
||||
this.cropEnabled.postValue(!this.cropEnabled.getValue());
|
||||
}
|
||||
|
||||
public LiveData<Boolean> isTorchEnabled() {
|
||||
return this.torchEnabled;
|
||||
}
|
||||
|
||||
public LiveData<Boolean> isLowResolutionEnabled() {
|
||||
return this.lowResolutionEnabled;
|
||||
}
|
||||
|
||||
public LiveData<Boolean> isCropEnabled() {
|
||||
return this.cropEnabled;
|
||||
}
|
||||
|
||||
public LiveData<Integer> getTorchToggleButtonImageResource() {
|
||||
return Transformations.map(isTorchEnabled(), enabled -> enabled
|
||||
? R.drawable.ic_baseline_flash_off_24
|
||||
: R.drawable.ic_baseline_flash_on_24);
|
||||
}
|
||||
|
||||
public LiveData<Integer> getLowResolutionToggleButtonImageResource() {
|
||||
return Transformations.map(isLowResolutionEnabled(), enabled -> enabled
|
||||
? R.drawable.ic_high_quality
|
||||
: R.drawable.ic_low_quality);
|
||||
}
|
||||
|
||||
public LiveData<Integer> getCropToggleButtonImageResource() {
|
||||
return Transformations.map(isCropEnabled(), enabled -> enabled
|
||||
? R.drawable.ic_crop_4_3
|
||||
: R.drawable.ic_crop_16_9);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,9 @@
|
|||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Marcel Hibbe
|
||||
* @author Andy Scherzinger
|
||||
* Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
|
||||
* Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
*
|
||||
* 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
|
||||
|
@ -24,47 +26,26 @@ import android.app.Activity
|
|||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import butterknife.BindView
|
||||
import butterknife.ButterKnife
|
||||
import butterknife.Unbinder
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.components.filebrowser.controllers.BrowserController
|
||||
import com.nextcloud.talk.controllers.ChatController
|
||||
import com.nextcloud.talk.databinding.DialogAttachmentBinding
|
||||
import com.nextcloud.talk.models.database.CapabilitiesUtil
|
||||
|
||||
class AttachmentDialog(val activity: Activity, var chatController: ChatController) : BottomSheetDialog(activity) {
|
||||
|
||||
@BindView(R.id.menu_share_location)
|
||||
@JvmField
|
||||
var shareLocationItem: LinearLayout? = null
|
||||
|
||||
@BindView(R.id.txt_share_location)
|
||||
@JvmField
|
||||
var shareLocation: AppCompatTextView? = null
|
||||
|
||||
@BindView(R.id.txt_attach_file_from_local)
|
||||
@JvmField
|
||||
var attachFromLocal: AppCompatTextView? = null
|
||||
|
||||
@BindView(R.id.txt_attach_file_from_cloud)
|
||||
@JvmField
|
||||
var attachFromCloud: AppCompatTextView? = null
|
||||
|
||||
private var unbinder: Unbinder? = null
|
||||
private lateinit var dialogAttachmentBinding: DialogAttachmentBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val view = layoutInflater.inflate(R.layout.dialog_attachment, null)
|
||||
setContentView(view)
|
||||
dialogAttachmentBinding = DialogAttachmentBinding.inflate(layoutInflater)
|
||||
setContentView(dialogAttachmentBinding.root)
|
||||
window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
unbinder = ButterKnife.bind(this, view)
|
||||
|
||||
var serverName = CapabilitiesUtil.getServerName(chatController.conversationUser)
|
||||
attachFromCloud?.text = chatController.resources?.let {
|
||||
dialogAttachmentBinding.txtAttachFileFromCloud.text = chatController.resources?.let {
|
||||
if (serverName.isNullOrEmpty()) {
|
||||
serverName = it.getString(R.string.nc_server_product_name)
|
||||
}
|
||||
|
@ -76,19 +57,25 @@ class AttachmentDialog(val activity: Activity, var chatController: ChatControlle
|
|||
"geo-location-sharing"
|
||||
)
|
||||
) {
|
||||
shareLocationItem?.visibility = View.GONE
|
||||
dialogAttachmentBinding.menuShareLocation.visibility = View.GONE
|
||||
}
|
||||
|
||||
shareLocation?.setOnClickListener {
|
||||
dialogAttachmentBinding.menuShareLocation.setOnClickListener {
|
||||
chatController.showShareLocationScreen()
|
||||
dismiss()
|
||||
}
|
||||
|
||||
attachFromLocal?.setOnClickListener {
|
||||
dialogAttachmentBinding.menuAttachFileFromLocal.setOnClickListener {
|
||||
chatController.sendSelectLocalFileIntent()
|
||||
dismiss()
|
||||
}
|
||||
attachFromCloud?.setOnClickListener {
|
||||
|
||||
dialogAttachmentBinding.menuAttachPictureFromCam.setOnClickListener {
|
||||
chatController.sendPictureFromCamIntent()
|
||||
dismiss()
|
||||
}
|
||||
|
||||
dialogAttachmentBinding.menuAttachFileFromCloud.setOnClickListener {
|
||||
chatController.showBrowserScreen(BrowserController.BrowserType.DAV_BROWSER)
|
||||
dismiss()
|
||||
}
|
||||
|
|
|
@ -206,7 +206,7 @@ public class ChooseAccountDialogFragment extends DialogFragment {
|
|||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
Boolean.TRUE,
|
||||
null, userEntity.getId(),
|
||||
null,
|
||||
null,
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* @author Andy Scherzinger
|
||||
* Copyright (C) 2021 Tobias Kaminsky <tobias.kaminsky@nextcloud.com>
|
||||
* Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
*
|
||||
* 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
|
||||
|
@ -24,11 +26,11 @@ import android.content.Context
|
|||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.controllers.ProfileController
|
||||
import com.nextcloud.talk.databinding.DialogScopeBinding
|
||||
import com.nextcloud.talk.models.json.userprofile.Scope
|
||||
|
||||
class ScopeDialog(
|
||||
|
@ -38,33 +40,36 @@ class ScopeDialog(
|
|||
private val position: Int
|
||||
) :
|
||||
BottomSheetDialog(con) {
|
||||
|
||||
private lateinit var dialogScopeBinding: DialogScopeBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val view = layoutInflater.inflate(R.layout.dialog_scope, null)
|
||||
setContentView(view)
|
||||
dialogScopeBinding = DialogScopeBinding.inflate(layoutInflater)
|
||||
setContentView(dialogScopeBinding.root)
|
||||
|
||||
window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
|
||||
if (field == ProfileController.Field.DISPLAYNAME || field == ProfileController.Field.EMAIL) {
|
||||
findViewById<LinearLayout>(R.id.scope_private)?.visibility = View.GONE
|
||||
dialogScopeBinding.scopePrivate.visibility = View.GONE
|
||||
}
|
||||
|
||||
findViewById<LinearLayout>(R.id.scope_private)?.setOnClickListener {
|
||||
dialogScopeBinding.scopePrivate.setOnClickListener {
|
||||
userInfoAdapter.updateScope(position, Scope.PRIVATE)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
findViewById<LinearLayout>(R.id.scope_local)?.setOnClickListener {
|
||||
dialogScopeBinding.scopeLocal.setOnClickListener {
|
||||
userInfoAdapter.updateScope(position, Scope.LOCAL)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
findViewById<LinearLayout>(R.id.scope_federated)?.setOnClickListener {
|
||||
dialogScopeBinding.scopeFederated.setOnClickListener {
|
||||
userInfoAdapter.updateScope(position, Scope.FEDERATED)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
findViewById<LinearLayout>(R.id.scope_published)?.setOnClickListener {
|
||||
dialogScopeBinding.scopePublished.setOnClickListener {
|
||||
userInfoAdapter.updateScope(position, Scope.PUBLISHED)
|
||||
dismiss()
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ object BitmapShrinker {
|
|||
private const val DEGREES_180 = 180f
|
||||
private const val DEGREES_270 = 270f
|
||||
|
||||
@JvmStatic
|
||||
fun shrinkBitmap(
|
||||
path: String,
|
||||
reqWidth: Int,
|
||||
|
|
|
@ -46,16 +46,13 @@ public class FileSortOrderBySize extends FileSortOrder {
|
|||
|
||||
Collections.sort(files, (o1, o2) -> {
|
||||
if (!o1.getModel().isFile() && !o2.getModel().isFile()) {
|
||||
Long obj1 = o1.getModel().size;
|
||||
return multiplier * obj1.compareTo(o2.getModel().getSize());
|
||||
return multiplier * Long.compare(o1.getModel().getSize(), o2.getModel().getSize());
|
||||
} else if (!o1.getModel().isFile()) {
|
||||
return -1;
|
||||
|
||||
} else if (!o2.getModel().isFile()) {
|
||||
return 1;
|
||||
} else {
|
||||
Long obj1 = o1.getModel().getSize();
|
||||
return multiplier * obj1.compareTo(o2.getModel().getSize());
|
||||
return multiplier * Long.compare(o1.getModel().getSize(), o2.getModel().getSize());
|
||||
}
|
||||
});
|
||||
|
||||
|
|
68
app/src/main/java/com/nextcloud/talk/utils/FileUtils.java
Normal file
68
app/src/main/java/com/nextcloud/talk/utils/FileUtils.java
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Andy Scherzinger
|
||||
* @author Stefan Niedermann
|
||||
* Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
* Copyright (C) 2021 Stefan Niedermann <info@niedermann.it>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class FileUtils {
|
||||
private static final String TAG = FileUtils.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Creates a new {@link File}
|
||||
*/
|
||||
public static File getTempCacheFile(@NonNull Context context, String fileName) throws IOException {
|
||||
File cacheFile = new File(context.getApplicationContext().getFilesDir().getAbsolutePath() + "/" + fileName);
|
||||
|
||||
Log.v(TAG, "Full path for new cache file:" + cacheFile.getAbsolutePath());
|
||||
|
||||
final File tempDir = cacheFile.getParentFile();
|
||||
if (tempDir == null) {
|
||||
throw new FileNotFoundException("could not cacheFile.getParentFile()");
|
||||
}
|
||||
if (!tempDir.exists()) {
|
||||
Log.v(TAG,
|
||||
"The folder in which the new file should be created does not exist yet. Trying to create it…");
|
||||
if (tempDir.mkdirs()) {
|
||||
Log.v(TAG, "Creation successful");
|
||||
} else {
|
||||
throw new IOException("Directory for temporary file does not exist and could not be created.");
|
||||
}
|
||||
}
|
||||
|
||||
Log.v(TAG, "- Try to create actual cache file");
|
||||
if (cacheFile.createNewFile()) {
|
||||
Log.v(TAG, "Successfully created cache file");
|
||||
} else {
|
||||
throw new IOException("Failed to create cacheFile");
|
||||
}
|
||||
|
||||
return cacheFile;
|
||||
}
|
||||
}
|
|
@ -60,7 +60,7 @@ import autodagger.AutoInjector;
|
|||
|
||||
@AutoInjector(NextcloudTalkApplication.class)
|
||||
public class MagicPeerConnectionWrapper {
|
||||
private static String TAG = "MagicPeerConnectionWrapper";
|
||||
private static final String TAG = "MagicPeerConWrapper";
|
||||
|
||||
private List<IceCandidate> iceCandidates = new ArrayList<>();
|
||||
private PeerConnection peerConnection;
|
||||
|
@ -129,7 +129,6 @@ public class MagicPeerConnectionWrapper {
|
|||
EventBus.getDefault().post(new WebSocketCommunicationEvent("peerReadyForRequestingOffer", hashMap));
|
||||
} else if (!hasMCU && hasInitiated) {
|
||||
peerConnection.createOffer(magicSdpObserver, sdpConstraints);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +177,6 @@ public class MagicPeerConnectionWrapper {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendNickChannelData(DataChannelMessageNick dataChannelMessage) {
|
||||
ByteBuffer buffer;
|
||||
if (magicDataChannel != null) {
|
||||
|
@ -186,7 +184,7 @@ public class MagicPeerConnectionWrapper {
|
|||
buffer = ByteBuffer.wrap(LoganSquare.serialize(dataChannelMessage).getBytes());
|
||||
magicDataChannel.send(new DataChannel.Buffer(buffer, false));
|
||||
} catch (IOException e) {
|
||||
Log.d(TAG, "Failed to send channel data, attempting regular " + dataChannelMessage.toString());
|
||||
Log.d(TAG, "Failed to send channel data, attempting regular " + dataChannelMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +196,7 @@ public class MagicPeerConnectionWrapper {
|
|||
buffer = ByteBuffer.wrap(LoganSquare.serialize(dataChannelMessage).getBytes());
|
||||
magicDataChannel.send(new DataChannel.Buffer(buffer, false));
|
||||
} catch (IOException e) {
|
||||
Log.d(TAG, "Failed to send channel data, attempting regular " + dataChannelMessage.toString());
|
||||
Log.d(TAG, "Failed to send channel data, attempting regular " + dataChannelMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
~ * You should have received a copy of the GNU General Public License
|
||||
~ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
~ */
|
||||
-->
|
||||
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#0082C9"/>
|
||||
<stroke android:color="#FFFFFF" android:width="2dp"/>
|
||||
<size android:width="15dp" android:height="15dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#0082C9" />
|
||||
<stroke android:width="2dp" android:color="#FFFFFF" />
|
||||
<size android:width="15dp" android:height="15dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
21
app/src/main/res/drawable/ic_baseline_flash_off_24.xml
Normal file
21
app/src/main/res/drawable/ic_baseline_flash_off_24.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector android:height="24dp" android:tint="#757575"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M3.27,3L2,4.27l5,5V13h3v9l3.58,-6.14L17.73,20 19,18.73 3.27,3zM17,10h-4l4,-8H7v2.18l8.46,8.46L17,10z"/>
|
||||
</vector>
|
21
app/src/main/res/drawable/ic_baseline_flash_on_24.xml
Normal file
21
app/src/main/res/drawable/ic_baseline_flash_on_24.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector android:height="24dp" android:tint="#757575"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M7,2v11h3v9l7,-12h-4l4,-8z"/>
|
||||
</vector>
|
|
@ -0,0 +1,32 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M9,12c0,1.66 1.34,3 3,3s3,-1.34 3,-3s-1.34,-3 -3,-3S9,10.34 9,12z"/>
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M8,10V8H5.09C6.47,5.61 9.05,4 12,4c3.72,0 6.85,2.56 7.74,6h2.06c-0.93,-4.56 -4.96,-8 -9.8,-8C8.73,2 5.82,3.58 4,6.01V4H2v6H8z"/>
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M16,14v2h2.91c-1.38,2.39 -3.96,4 -6.91,4c-3.72,0 -6.85,-2.56 -7.74,-6H2.2c0.93,4.56 4.96,8 9.8,8c3.27,0 6.18,-1.58 8,-4.01V20h2v-6H16z"/>
|
||||
</vector>
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
22
app/src/main/res/drawable/ic_baseline_photo_camera_24.xml
Normal file
22
app/src/main/res/drawable/ic_baseline_photo_camera_24.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector android:autoMirrored="true" android:height="24dp"
|
||||
android:tint="#757575" android:viewportHeight="24"
|
||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
|
||||
</vector>
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector android:autoMirrored="true" android:height="24dp"
|
||||
android:tint="@color/medium_emphasis_text" android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
|
29
app/src/main/res/drawable/ic_crop_16_9.xml
Normal file
29
app/src/main/res/drawable/ic_crop_16_9.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<!--
|
||||
~ Nextcloud Talk application
|
||||
~
|
||||
~ @author Andy Scherzinger
|
||||
~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
~
|
||||
~ 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.
|
||||
~
|
||||
~ This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M21,16L21,17C21,18.1 20.1,19 19,19L5,19C3.9,19 3,18.1 3,17L3,16L5,16L5,17L19,17L19,16L21,16ZM3,8L3,7C3,5.9 3.9,5 5,5L19,5C20.1,5 21,5.9 21,7L21,8L19,8L19,7L5,7L5,8L3,8ZM21,14.014C21,14.564 20.55,15.014 20,15.014L16.5,15.014L16.5,13.514L19.5,13.514L19.5,12.514L17.5,12.514C16.95,12.514 16.5,12.064 16.5,11.514L16.5,10.014C16.5,9.464 16.95,9.014 17.5,9.014L20,9.014C20.55,9.014 21,9.464 21,10.014L21,14.014ZM6,15L4.5,15L4.5,10.5L3,10.5L3,9L6,9L6,15ZM8,15C7.45,15 7,14.55 7,14L7,10C7,9.45 7.45,9 8,9L11.5,9L11.5,10.5L8.5,10.5L8.5,11.5L10.5,11.5C11.05,11.5 11.5,11.95 11.5,12.5L11.5,14C11.5,14.55 11.05,15 10.5,15L8,15ZM14.75,12.722L13.25,12.722L13.25,14.223L14.75,14.223L14.75,12.722ZM9.995,12.456L8.495,12.456L8.495,13.956L9.995,13.956L9.995,12.456ZM19.508,9.984L18.008,9.984L18.008,11.484L19.508,11.484L19.508,9.984ZM14.75,9.722L13.25,9.722L13.25,11.223L14.75,11.223L14.75,9.722Z" />
|
||||
</vector>
|
29
app/src/main/res/drawable/ic_crop_4_3.xml
Normal file
29
app/src/main/res/drawable/ic_crop_4_3.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<!--
|
||||
~ Nextcloud Talk application
|
||||
~
|
||||
~ @author Andy Scherzinger
|
||||
~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
~
|
||||
~ 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.
|
||||
~
|
||||
~ This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M21,16L21,17C21,18.1 20.1,19 19,19L5,19C3.9,19 3,18.1 3,17L3,16L5,16L5,17L19,17L19,16L21,16ZM19,14L19,10C19,9.45 18.55,9 18,9L14.5,9L14.5,10.5L17.5,10.5L17.5,11.5L15.5,11.5L15.5,12.5L17.5,12.5L17.5,13.5L14.5,13.5L14.5,15L18,15C18.55,15 19,14.55 19,14ZM9.5,9L9.5,15L8,15L8,13.5L5,13.5L5,9L6.5,9L6.5,12L8,12L8,9L9.5,9ZM12.75,12.723L12.75,14.223L11.25,14.223L11.25,12.723L12.75,12.723ZM12.75,9.723L12.75,11.223L11.25,11.223L11.25,9.723L12.75,9.723ZM3,8L3,7C3,5.9 3.9,5 5,5L19,5C20.1,5 21,5.9 21,7L21,8L19,8L19,7L5,7L5,8L3,8Z" />
|
||||
</vector>
|
26
app/src/main/res/drawable/ic_high_quality.xml
Normal file
26
app/src/main/res/drawable/ic_high_quality.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,4L5,4c-1.11,0 -2,0.9 -2,2v12c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.9,-2 -2,-2zM11,15L9.5,15v-2h-2v2L6,15L6,9h1.5v2.5h2L9.5,9L11,9v6zM18,14c0,0.55 -0.45,1 -1,1h-0.75v1.5h-1.5L14.75,15L14,15c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h3c0.55,0 1,0.45 1,1v4zM14.5,13.5h2v-3h-2v3z"/>
|
||||
</vector>
|
29
app/src/main/res/drawable/ic_low_quality.xml
Normal file
29
app/src/main/res/drawable/ic_low_quality.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<!--
|
||||
~ Nextcloud Talk application
|
||||
~
|
||||
~ @author Andy Scherzinger
|
||||
~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
~
|
||||
~ 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.
|
||||
~
|
||||
~ This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19,4L5,4C3.89,4 3,4.9 3,6L3,18C3,19.1 3.89,20 5,20L19,20C20.1,20 21,19.1 21,18L21,6C21,4.9 20.1,4 19,4ZM18,14C18,14.55 17.55,15 17,15L16.25,15L16.25,16.5L14.75,16.5L14.75,15L14,15C13.45,15 13,14.55 13,14L13,10C13,9.45 13.45,9 14,9L17,9C17.55,9 18,9.45 18,10L18,14ZM7.5,13.5L10.509,13.496L10.508,14.997L6,15L6,9L7.5,9L7.5,13.5ZM14.5,13.5L16.5,13.5L16.5,10.5L14.5,10.5L14.5,13.5Z"
|
||||
android:fillType="nonZero"/>
|
||||
</vector>
|
|
@ -1,3 +1,19 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
|
|
23
app/src/main/res/drawable/ic_refresh.xml
Normal file
23
app/src/main/res/drawable/ic_refresh.xml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path android:fillColor="#000" android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z" />
|
||||
</vector>
|
|
@ -1,5 +1,27 @@
|
|||
<vector android:autoMirrored="true" android:height="24dp"
|
||||
android:tint="@color/medium_emphasis_text" android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M10,9V5l-7,7 7,7v-4.1c5,0 8.5,1.6 11,5.1 -1,-5 -4,-10 -11,-11z"/>
|
||||
<!--
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:autoMirrored="true"
|
||||
android:tint="@color/medium_emphasis_text"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M10,9V5l-7,7 7,7v-4.1c5,0 8.5,1.6 11,5.1 -1,-5 -4,-10 -11,-11z" />
|
||||
</vector>
|
||||
|
|
|
@ -15,9 +15,11 @@
|
|||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path android:fillColor="#757575" android:pathData="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z" />
|
||||
<path
|
||||
android:fillColor="#757575"
|
||||
android:pathData="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z" />
|
||||
</vector>
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
<!--
|
||||
Nextcloud Talk application
|
||||
@author Google LLC
|
||||
Copyright (C) 2021 Google LLC
|
||||
|
||||
Copyright (C) 2020 Nextcloud.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or any later version.
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
This program 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 AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public
|
||||
License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Icon provided by Android Material Library in Apache License 2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector android:height="24dp" android:tint="#666666"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M19.1,12.9a2.8,2.8 0,0 0,0.1 -0.9,2.8 2.8,0 0,0 -0.1,-0.9l2.1,-1.6a0.7,0.7 0,0 0,0.1 -0.6L19.4,5.5a0.7,0.7 0,0 0,-0.6 -0.2l-2.4,1a6.5,6.5 0,0 0,-1.6 -0.9l-0.4,-2.6a0.5,0.5 0,0 0,-0.5 -0.4H10.1a0.5,0.5 0,0 0,-0.5 0.4L9.3,5.4a5.6,5.6 0,0 0,-1.7 0.9l-2.4,-1a0.4,0.4 0,0 0,-0.5 0.2l-2,3.4c-0.1,0.2 0,0.4 0.2,0.6l2,1.6a2.8,2.8 0,0 0,-0.1 0.9,2.8 2.8,0 0,0 0.1,0.9L2.8,14.5a0.7,0.7 0,0 0,-0.1 0.6l1.9,3.4a0.7,0.7 0,0 0,0.6 0.2l2.4,-1a6.5,6.5 0,0 0,1.6 0.9l0.4,2.6a0.5,0.5 0,0 0,0.5 0.4h3.8a0.5,0.5 0,0 0,0.5 -0.4l0.3,-2.6a5.6,5.6 0,0 0,1.7 -0.9l2.4,1a0.4,0.4 0,0 0,0.5 -0.2l2,-3.4c0.1,-0.2 0,-0.4 -0.2,-0.6ZM12,15.6A3.6,3.6 0,1 1,15.6 12,3.6 3.6,0 0,1 12,15.6Z"/>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#666666"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19.1,12.9a2.8,2.8 0,0 0,0.1 -0.9,2.8 2.8,0 0,0 -0.1,-0.9l2.1,-1.6a0.7,0.7 0,0 0,0.1 -0.6L19.4,5.5a0.7,0.7 0,0 0,-0.6 -0.2l-2.4,1a6.5,6.5 0,0 0,-1.6 -0.9l-0.4,-2.6a0.5,0.5 0,0 0,-0.5 -0.4H10.1a0.5,0.5 0,0 0,-0.5 0.4L9.3,5.4a5.6,5.6 0,0 0,-1.7 0.9l-2.4,-1a0.4,0.4 0,0 0,-0.5 0.2l-2,3.4c-0.1,0.2 0,0.4 0.2,0.6l2,1.6a2.8,2.8 0,0 0,-0.1 0.9,2.8 2.8,0 0,0 0.1,0.9L2.8,14.5a0.7,0.7 0,0 0,-0.1 0.6l1.9,3.4a0.7,0.7 0,0 0,0.6 0.2l2.4,-1a6.5,6.5 0,0 0,1.6 0.9l0.4,2.6a0.5,0.5 0,0 0,0.5 0.4h3.8a0.5,0.5 0,0 0,0.5 -0.4l0.3,-2.6a5.6,5.6 0,0 0,1.7 -0.9l2.4,1a0.4,0.4 0,0 0,0.5 -0.2l2,-3.4c0.1,-0.2 0,-0.4 -0.2,-0.6ZM12,15.6A3.6,3.6 0,1 1,15.6 12,3.6 3.6,0 0,1 12,15.6Z" />
|
||||
</vector>
|
||||
|
|
236
app/src/main/res/layout/activity_take_picture.xml
Normal file
236
app/src/main/res/layout/activity_take_picture.xml
Normal file
|
@ -0,0 +1,236 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Nextcloud Talk application
|
||||
~
|
||||
~ @author Andy Scherzinger
|
||||
~ @author Stefan Niedermann
|
||||
~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
~ Copyright (C) 2021 Stefan Niedermann <info@niedermann.it>
|
||||
~
|
||||
~ 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.
|
||||
~
|
||||
~ This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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:background="@android:color/black"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:theme="@style/TransparentTheme">
|
||||
|
||||
<androidx.camera.view.PreviewView
|
||||
android:id="@+id/preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:scaleType="fitCenter" />
|
||||
|
||||
<com.github.chrisbanes.photoview.PhotoView
|
||||
android:id="@+id/photo_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="fitCenter"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/toggle_crop"
|
||||
style="@style/Widget.AppTheme.Button.IconButton"
|
||||
android:layout_width="@dimen/min_size_clickable_area"
|
||||
android:layout_height="@dimen/min_size_clickable_area"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginStart="0dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:contentDescription="@string/take_photo_toggle_crop"
|
||||
android:insetLeft="4dp"
|
||||
android:insetTop="4dp"
|
||||
android:insetRight="4dp"
|
||||
android:insetBottom="4dp"
|
||||
android:tint="@color/white"
|
||||
app:backgroundTint="@color/camera_bg_tint"
|
||||
app:cornerRadius="@dimen/button_corner_radius"
|
||||
app:elevation="0dp"
|
||||
app:icon="@drawable/ic_crop_16_9"
|
||||
app:iconGravity="textStart"
|
||||
app:iconPadding="0dp"
|
||||
app:iconSize="24dp"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/takePhoto"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/toggle_lowres"
|
||||
style="@style/Widget.AppTheme.Button.IconButton"
|
||||
android:layout_width="@dimen/min_size_clickable_area"
|
||||
android:layout_height="@dimen/min_size_clickable_area"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:contentDescription="@string/take_photo_toggle_lowres"
|
||||
android:insetLeft="4dp"
|
||||
android:insetTop="4dp"
|
||||
android:insetRight="4dp"
|
||||
android:insetBottom="4dp"
|
||||
android:padding="0dp"
|
||||
android:tint="@android:color/white"
|
||||
app:backgroundTint="@color/camera_bg_tint"
|
||||
app:cornerRadius="@dimen/button_corner_radius"
|
||||
app:elevation="0dp"
|
||||
app:icon="@drawable/ic_low_quality"
|
||||
app:iconGravity="textStart"
|
||||
app:iconPadding="0dp"
|
||||
app:iconSize="24dp"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/takePhoto" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/toggle_torch"
|
||||
style="@style/Widget.AppTheme.Button.IconButton"
|
||||
android:layout_width="@dimen/min_size_clickable_area"
|
||||
android:layout_height="@dimen/min_size_clickable_area"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginStart="0dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:contentDescription="@string/take_photo_toggle_torch"
|
||||
android:insetLeft="4dp"
|
||||
android:insetTop="4dp"
|
||||
android:insetRight="4dp"
|
||||
android:insetBottom="4dp"
|
||||
android:tint="@color/white"
|
||||
app:backgroundTint="@color/camera_bg_tint"
|
||||
app:cornerRadius="@dimen/button_corner_radius"
|
||||
app:elevation="0dp"
|
||||
app:icon="@drawable/ic_baseline_flash_on_24"
|
||||
app:iconGravity="textStart"
|
||||
app:iconPadding="0dp"
|
||||
app:iconSize="24dp"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="@id/takePhoto"
|
||||
app:layout_constraintEnd_toStartOf="@id/takePhoto"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/switchCamera"
|
||||
style="@style/Widget.AppTheme.Button.IconButton"
|
||||
android:layout_width="@dimen/min_size_clickable_area"
|
||||
android:layout_height="@dimen/min_size_clickable_area"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:contentDescription="@string/take_photo_switch_camera"
|
||||
android:insetLeft="4dp"
|
||||
android:insetTop="4dp"
|
||||
android:insetRight="4dp"
|
||||
android:insetBottom="4dp"
|
||||
android:padding="0dp"
|
||||
android:tint="@android:color/white"
|
||||
app:backgroundTint="@color/camera_bg_tint"
|
||||
app:cornerRadius="@dimen/button_corner_radius"
|
||||
app:elevation="0dp"
|
||||
app:icon="@drawable/ic_baseline_flip_camera_android_24"
|
||||
app:iconGravity="textStart"
|
||||
app:iconPadding="0dp"
|
||||
app:iconSize="24dp"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="@id/takePhoto"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/takePhoto" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/retake"
|
||||
style="@style/Widget.AppTheme.Button.IconButton"
|
||||
android:layout_width="@dimen/min_size_clickable_area"
|
||||
android:layout_height="@dimen/min_size_clickable_area"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:contentDescription="@string/take_photo_retake_photo"
|
||||
android:insetLeft="0dp"
|
||||
android:insetTop="0dp"
|
||||
android:insetRight="0dp"
|
||||
android:insetBottom="0dp"
|
||||
android:padding="0dp"
|
||||
android:tint="@android:color/white"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="@color/camera_bg_tint"
|
||||
app:cornerRadius="@dimen/button_corner_radius"
|
||||
app:elevation="0dp"
|
||||
app:icon="@drawable/ic_refresh"
|
||||
app:iconGravity="textStart"
|
||||
app:iconPadding="0dp"
|
||||
app:iconSize="24dp"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="@id/takePhoto"
|
||||
app:layout_constraintEnd_toStartOf="@id/takePhoto"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/takePhoto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="@dimen/standard_double_margin"
|
||||
android:contentDescription="@string/take_photo"
|
||||
android:tint="@android:color/white"
|
||||
app:backgroundTint="@color/colorPrimary"
|
||||
app:fabCustomSize="72dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:srcCompat="@drawable/ic_baseline_photo_camera_24" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/send"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:contentDescription="@string/take_photo_switch_camera"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:text="@string/take_photo_send"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
android:theme="@style/Button.Primary"
|
||||
android:tint="@android:color/white"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="@color/colorPrimary"
|
||||
app:cornerRadius="48dp"
|
||||
app:elevation="0dp"
|
||||
app:icon="@drawable/ic_send"
|
||||
app:iconGravity="textStart"
|
||||
app:iconPadding="8dp"
|
||||
app:iconSize="24dp"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="@id/takePhoto"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/takePhoto" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -105,6 +105,39 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/menu_attach_picture_from_cam"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="@dimen/standard_padding"
|
||||
android:paddingTop="@dimen/standard_half_padding"
|
||||
android:paddingRight="@dimen/standard_padding"
|
||||
android:paddingBottom="@dimen/standard_half_padding"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/menu_icon_attach_picture_from_cam"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_baseline_photo_camera_24"
|
||||
app:tint="@color/colorPrimary" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/txt_attach_picture_from_cam"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="@dimen/standard_margin"
|
||||
android:text="@string/nc_upload_picture_from_cam"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="@color/high_emphasis_text"
|
||||
android:textSize="@dimen/bottom_sheet_text_size" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/menu_attach_file_from_cloud"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -89,4 +89,6 @@
|
|||
<!-- voicemessage -->
|
||||
<color name="nc_voice_message_outgoing_controls">#606060</color>
|
||||
|
||||
<color name="camera_bg_tint">#99121212</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -389,6 +389,7 @@
|
|||
<!-- Upload -->
|
||||
<string name="nc_add_file">Add to conversation</string>
|
||||
<string name="nc_upload_local_file">Upload local file</string>
|
||||
<string name="nc_upload_picture_from_cam">Take photo</string>
|
||||
<string name="nc_upload_from_cloud">Share from %1$s</string>
|
||||
<string name="nc_upload_failed">Sorry, upload failed</string>
|
||||
<string name="nc_upload_choose_local_files">Choose files</string>
|
||||
|
@ -473,4 +474,13 @@
|
|||
<string name="nc_dialog_invalid_password">Invalid password</string>
|
||||
<string name="nc_dialog_reauth_or_delete">Do you want to reauthorize or delete this account?</string>
|
||||
|
||||
<string name="take_photo">Take a photo</string>
|
||||
<string name="take_photo_switch_camera">Switch camera</string>
|
||||
<string name="take_photo_retake_photo">Re-take photo</string>
|
||||
<string name="take_photo_toggle_torch">Toggle torch</string>
|
||||
<string name="take_photo_toggle_crop">Crop photo</string>
|
||||
<string name="take_photo_toggle_lowres">Reduce image size</string>
|
||||
<string name="take_photo_send">Send</string>
|
||||
<string name="take_photo_error_deleting_picture">Error taking picture</string>
|
||||
<string name="take_photo_permission">Taking a photo is not possible without permissions</string>
|
||||
</resources>
|
||||
|
|
|
@ -55,6 +55,18 @@
|
|||
<item name="elevation">1dp</item>
|
||||
</style>
|
||||
|
||||
<style name="TransparentTheme" parent="Theme.MaterialComponents.NoActionBar.Bridge">
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowBackground">@android:color/background_dark</item>
|
||||
<item name="android:colorBackgroundCacheHint">@null</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
</style>
|
||||
|
||||
<style name="TakePhotoTheme" parent="TransparentTheme">
|
||||
<item name="android:windowFullscreen">true</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
</style>
|
||||
|
||||
<style name="ErrorAppearance" parent="@android:style/TextAppearance">
|
||||
<item name="android:textColor">@color/nc_darkRed</item>
|
||||
<item name="android:textSize">12sp</item>
|
||||
|
@ -103,6 +115,21 @@
|
|||
<item name="searchHintIcon">@null</item>
|
||||
</style>
|
||||
|
||||
<style name="Button" parent="Widget.MaterialComponents.Button.UnelevatedButton">
|
||||
<item name="colorButtonNormal">@color/colorPrimary</item>
|
||||
<item name="android:textColor">@color/white</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
<item name="android:typeface">sans</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
<style name="Button.Primary" parent="Button">
|
||||
<item name="colorButtonNormal">@color/colorPrimary</item>
|
||||
<item name="android:textColor">@color/white</item>
|
||||
<item name="android:typeface">sans</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.AppTheme.Button.IconButton" parent="Widget.MaterialComponents.Button.TextButton">
|
||||
<item name="android:minWidth">0dp</item>
|
||||
<item name="android:insetLeft">0dp</item>
|
||||
|
|
5
drawable_resources/other/ic_crop_16_9.svg
Normal file
5
drawable_resources/other/ic_crop_16_9.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="M21,16L21,17C21,18.1 20.1,19 19,19L5,19C3.9,19 3,18.1 3,17L3,16L5,16L5,17L19,17L19,16L21,16ZM3,8L3,7C3,5.9 3.9,5 5,5L19,5C20.1,5 21,5.9 21,7L21,8L19,8L19,7L5,7L5,8L3,8ZM21,14.014C21,14.564 20.55,15.014 20,15.014L16.5,15.014L16.5,13.514L19.5,13.514L19.5,12.514L17.5,12.514C16.95,12.514 16.5,12.064 16.5,11.514L16.5,10.014C16.5,9.464 16.95,9.014 17.5,9.014L20,9.014C20.55,9.014 21,9.464 21,10.014L21,14.014ZM6,15L4.5,15L4.5,10.5L3,10.5L3,9L6,9L6,15ZM8,15C7.45,15 7,14.55 7,14L7,10C7,9.45 7.45,9 8,9L11.5,9L11.5,10.5L8.5,10.5L8.5,11.5L10.5,11.5C11.05,11.5 11.5,11.95 11.5,12.5L11.5,14C11.5,14.55 11.05,15 10.5,15L8,15ZM14.75,12.722L13.25,12.722L13.25,14.223L14.75,14.223L14.75,12.722ZM9.995,12.456L8.495,12.456L8.495,13.956L9.995,13.956L9.995,12.456ZM19.508,9.984L18.008,9.984L18.008,11.484L19.508,11.484L19.508,9.984ZM14.75,9.722L13.25,9.722L13.25,11.223L14.75,11.223L14.75,9.722Z" style="fill-rule:nonzero;"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
5
drawable_resources/other/ic_crop_4_3.svg
Normal file
5
drawable_resources/other/ic_crop_4_3.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="M21,16L21,17C21,18.1 20.1,19 19,19L5,19C3.9,19 3,18.1 3,17L3,16L5,16L5,17L19,17L19,16L21,16ZM19,14L19,10C19,9.45 18.55,9 18,9L14.5,9L14.5,10.5L17.5,10.5L17.5,11.5L15.5,11.5L15.5,12.5L17.5,12.5L17.5,13.5L14.5,13.5L14.5,15L18,15C18.55,15 19,14.55 19,14ZM9.5,9L9.5,15L8,15L8,13.5L5,13.5L5,9L6.5,9L6.5,12L8,12L8,9L9.5,9ZM12.75,12.723L12.75,14.223L11.25,14.223L11.25,12.723L12.75,12.723ZM12.75,9.723L12.75,11.223L11.25,11.223L11.25,9.723L12.75,9.723ZM3,8L3,7C3,5.9 3.9,5 5,5L19,5C20.1,5 21,5.9 21,7L21,8L19,8L19,7L5,7L5,8L3,8Z" style="fill-rule:nonzero;"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1,015 B |
5
drawable_resources/other/ic_low_quality.svg
Normal file
5
drawable_resources/other/ic_low_quality.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="M19,4L5,4C3.89,4 3,4.9 3,6L3,18C3,19.1 3.89,20 5,20L19,20C20.1,20 21,19.1 21,18L21,6C21,4.9 20.1,4 19,4ZM18,14C18,14.55 17.55,15 17,15L16.25,15L16.25,16.5L14.75,16.5L14.75,15L14,15C13.45,15 13,14.55 13,14L13,10C13,9.45 13.45,9 14,9L17,9C17.55,9 18,9.45 18,10L18,14ZM7.5,13.5L10.509,13.496L10.508,14.997L6,15L6,9L7.5,9L7.5,13.5ZM14.5,13.5L16.5,13.5L16.5,10.5L14.5,10.5L14.5,13.5Z" style="fill-rule:nonzero;"/>
|
||||
</svg>
|
After Width: | Height: | Size: 872 B |
|
@ -1 +1 @@
|
|||
568
|
||||
559
|
|
@ -1,2 +1,2 @@
|
|||
DO NOT TOUCH; GENERATED BY DRONE
|
||||
<span class="mdl-layout-title">Lint Report: 1 error and 238 warnings</span>
|
||||
<span class="mdl-layout-title">Lint Report: 1 error and 222 warnings</span>
|
||||
|
|
Loading…
Reference in a new issue