diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index 6faea7699..c45ce9ecf 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -33,7 +33,7 @@ jobs: echo "pr=${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT" echo "repo=${{ github.event.pull_request.head.repo.full_name }}" >> "$GITHUB_OUTPUT" fi - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: ${{ steps.get-vars.outputs.repo }} ref: ${{ steps.get-vars.outputs.branch }} diff --git a/.github/workflows/assembleFlavors.yml b/.github/workflows/assembleFlavors.yml index edf158d31..e8820ed83 100644 --- a/.github/workflows/assembleFlavors.yml +++ b/.github/workflows/assembleFlavors.yml @@ -19,7 +19,7 @@ jobs: matrix: flavor: [ Generic, Gplay ] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - name: set up JDK 17 uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 with: diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 772b37a41..a4f88765f 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -19,7 +19,7 @@ jobs: matrix: task: [ detekt, ktlintCheck ] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - name: Set up JDK 17 uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 with: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 38a7a6855..3acb98573 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,13 +26,13 @@ jobs: language: [ 'java' ] steps: - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - name: Set Swap Space uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0 with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@a09933a12a80f87b87005513f0abb1494c27a716 # v2.21.4 + uses: github/codeql-action/init@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5 with: languages: ${{ matrix.language }} - name: Set up JDK 17 @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a09933a12a80f87b87005513f0abb1494c27a716 # v2.21.4 + uses: github/codeql-action/analyze@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5 diff --git a/.github/workflows/command-rebase.yml b/.github/workflows/command-rebase.yml index d7c3399ba..2e73d9935 100644 --- a/.github/workflows/command-rebase.yml +++ b/.github/workflows/command-rebase.yml @@ -31,7 +31,7 @@ jobs: reaction-type: "+1" - name: Checkout the latest code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: fetch-depth: 0 token: ${{ secrets.COMMAND_BOT_PAT }} diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 5e42770e8..b3c59d750 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -18,5 +18,5 @@ jobs: name: "Validation" runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4 # v1.1.0 diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index bf7ef8a69..55da4398f 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -19,7 +19,7 @@ jobs: - name: Check if secrets are available run: echo "::set-output name=ok::${{ secrets.KS_PASS != '' }}" id: check-secrets - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 if: ${{ steps.check-secrets.outputs.ok == 'true' }} - name: set up JDK 17 uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index c0a2f471e..ed0861e45 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -24,7 +24,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: persist-credentials: false @@ -37,6 +37,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@a09933a12a80f87b87005513f0abb1494c27a716 # v2.21.4 + uses: github/codeql-action/upload-sarif@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5 with: sarif_file: results.sarif diff --git a/app/build.gradle b/app/build.gradle index fa2a4cd2c..ba4d95e13 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -46,8 +46,8 @@ android { // mayor.minor.hotfix.increment (for increment: 01-50=Alpha / 51-89=RC / 90-99=stable) // xx .xxx .xx .xx - versionCode 170100017 - versionName "17.10.0 Alpha 17" + versionCode 170100020 + versionName "17.10.0 Alpha 20" flavorDimensions "default" renderscriptTargetApi 19 @@ -152,6 +152,7 @@ ext { roomVersion = "2.5.2" workVersion = "2.8.1" espressoVersion = "3.5.1" + media3_version = "1.1.1" } configurations.all { @@ -263,7 +264,9 @@ dependencies { implementation "com.afollestad.material-dialogs:lifecycle:${materialDialogsVersion}" implementation 'com.google.code.gson:gson:2.10.1' - implementation 'com.google.android.exoplayer:exoplayer:2.19.0' + + implementation "androidx.media3:media3-exoplayer:$media3_version" + implementation "androidx.media3:media3-ui:$media3_version" implementation 'com.github.chrisbanes:PhotoView:2.3.0' implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.27' @@ -273,8 +276,7 @@ dependencies { implementation "io.noties.markwon:ext-tasklist:$markwonVersion" implementation 'com.github.nextcloud-deps:ImagePicker:2.1.0.2' - implementation 'com.elyeproj.libraries:loaderviewlibrary:2.0.0' - + implementation 'io.github.elye:loaderviewlibrary:3.0.0' implementation 'org.osmdroid:osmdroid-android:6.1.16' implementation ('fr.dudie:nominatim-api:3.4', { //noinspection DuplicatePlatformClasses @@ -284,7 +286,7 @@ dependencies { implementation 'androidx.core:core-ktx:1.10.1' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-core:5.4.0' + testImplementation 'org.mockito:mockito-core:5.5.0' testImplementation 'androidx.arch.core:core-testing:2.2.0' androidTestImplementation "androidx.test:core:1.5.0" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f67a1a692..027cbc6f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -159,17 +159,17 @@ + android:theme="@style/FullScreenImageTheme"/> + android:theme="@style/FullScreenMediaTheme"/> + android:theme="@style/FullScreenTextTheme"/> raiseHandViewModel!!.lowerHand() } @@ -1437,7 +1443,7 @@ class CallActivity : CallBaseActivity() { } override fun onError(e: Throwable) { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding!!.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() Log.e(TAG, "Failed to fetch capabilities", e) // unused atm } @@ -1632,10 +1638,10 @@ class CallActivity : CallBaseActivity() { private fun showCallRunningSinceOneHourOrMoreInfo() { binding!!.callDuration.setTypeface(null, Typeface.BOLD) vibrateShort(context) - Toast.makeText( - context, + Snackbar.make( + binding!!.root, context.resources.getString(R.string.call_running_since_one_hour), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() } @@ -1909,7 +1915,7 @@ class CallActivity : CallBaseActivity() { } override fun onError(e: Throwable) { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding!!.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() Log.e(TAG, "Error while leaving the call", e) } @@ -2091,10 +2097,10 @@ class CallActivity : CallBaseActivity() { } else { if (peerConnectionFactory == null) { Log.e(TAG, "peerConnectionFactory was null in getOrCreatePeerConnectionWrapperForSessionIdAndType") - Toast.makeText( - context, + Snackbar.make( + binding!!.root, context.resources.getString(R.string.nc_common_error_sorry), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() hangup(true) return null @@ -2723,10 +2729,10 @@ class CallActivity : CallBaseActivity() { } raisedHand = true val nick = callParticipantModel.nick - Toast.makeText( - context, + Snackbar.make( + binding!!.root, String.format(context.resources.getString(R.string.nc_call_raised_hand), nick), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() } diff --git a/app/src/main/java/com/nextcloud/talk/activities/FullScreenImageActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/FullScreenImageActivity.kt index ddd5c0813..999c6e7fa 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/FullScreenImageActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/activities/FullScreenImageActivity.kt @@ -32,9 +32,9 @@ import android.util.Log import android.view.Menu import android.view.MenuItem import android.view.View -import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.content.FileProvider +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R import com.nextcloud.talk.databinding.ActivityFullScreenImageBinding @@ -133,7 +133,7 @@ class FullScreenImageActivity : AppCompatActivity() { // info that 100MB is the limit comes from https://stackoverflow.com/a/53334563 if (bitmapSize > HUNDRED_MB) { Log.e(TAG, "bitmap will be too large to display. It won't be displayed to avoid RuntimeException") - Toast.makeText(this, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } else { binding.photoView.setImageBitmap(bitmap) } diff --git a/app/src/main/java/com/nextcloud/talk/activities/FullScreenMediaActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/FullScreenMediaActivity.kt index 7a665183d..c9b4711f5 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/FullScreenMediaActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/activities/FullScreenMediaActivity.kt @@ -4,9 +4,11 @@ * @author Marcel Hibbe * @author Andy Scherzinger * @author Ezhil Shanmugham + * @author Parneet Singh * Copyright (C) 2021 Andy Scherzinger * Copyright (C) 2021 Marcel Hibbe * Copyright (C) 2023 Ezhil Shanmugham + * Copyright (c) 2023 Parneet Singh * * 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 @@ -30,13 +32,15 @@ import android.view.Menu import android.view.MenuItem import android.view.View import android.view.WindowManager +import androidx.annotation.OptIn import androidx.appcompat.app.AppCompatActivity import androidx.core.content.FileProvider +import androidx.media3.common.MediaItem +import androidx.media3.common.Player +import androidx.media3.common.util.UnstableApi +import androidx.media3.exoplayer.ExoPlayer +import androidx.media3.ui.PlayerView import autodagger.AutoInjector -import com.google.android.exoplayer2.MediaItem -import com.google.android.exoplayer2.Player -import com.google.android.exoplayer2.SimpleExoPlayer -import com.google.android.exoplayer2.ui.StyledPlayerView import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication @@ -49,7 +53,10 @@ class FullScreenMediaActivity : AppCompatActivity(), Player.Listener { lateinit var binding: ActivityFullScreenMediaBinding private lateinit var path: String - private lateinit var player: SimpleExoPlayer + private var player: ExoPlayer? = null + + private var playWhenReadyState: Boolean = true + private var playBackPosition: Long = 0L override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_preview, menu) @@ -81,6 +88,7 @@ class FullScreenMediaActivity : AppCompatActivity(), Player.Listener { } } + @OptIn(UnstableApi::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -104,7 +112,7 @@ class FullScreenMediaActivity : AppCompatActivity(), Player.Listener { } binding.playerView.setControllerVisibilityListener( - StyledPlayerView.ControllerVisibilityListener { v -> + PlayerView.ControllerVisibilityListener { v -> if (v != 0) { hideSystemUI() supportActionBar?.hide() @@ -119,11 +127,7 @@ class FullScreenMediaActivity : AppCompatActivity(), Player.Listener { override fun onStart() { super.onStart() initializePlayer() - - val mediaItem: MediaItem = MediaItem.fromUri(path) - player.setMediaItem(mediaItem) - player.prepare() - player.play() + preparePlayer() } override fun onStop() { @@ -132,14 +136,28 @@ class FullScreenMediaActivity : AppCompatActivity(), Player.Listener { } private fun initializePlayer() { - player = SimpleExoPlayer.Builder(applicationContext).build() + player = ExoPlayer.Builder(applicationContext).build() binding.playerView.player = player - player.playWhenReady = true - player.addListener(this) + player?.addListener(this) + } + + private fun preparePlayer() { + val mediaItem: MediaItem = MediaItem.fromUri(path) + player?.let { exoPlayer -> + exoPlayer.setMediaItem(mediaItem) + exoPlayer.playWhenReady = playWhenReadyState + exoPlayer.seekTo(playBackPosition) + exoPlayer.prepare() + } } private fun releasePlayer() { - player.release() + player?.let { exoPlayer -> + playBackPosition = exoPlayer.currentPosition + playWhenReadyState = exoPlayer.playWhenReady + exoPlayer.release() + } + player = null } private fun hideSystemUI() { diff --git a/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java b/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java index e7743ca2a..3159decff 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java @@ -37,8 +37,7 @@ import android.view.OrientationEventListener; import android.view.ScaleGestureDetector; import android.view.Surface; import android.view.View; -import android.widget.Toast; - +import com.google.android.material.snackbar.Snackbar; import com.google.common.util.concurrent.ListenableFuture; import com.nextcloud.talk.R; import com.nextcloud.talk.application.NextcloudTalkApplication; @@ -234,7 +233,7 @@ public class TakePhotoActivity extends AppCompatActivity { 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(); + Snackbar.make(binding.getRoot(), e.getMessage(), Snackbar.LENGTH_LONG).show(); finish(); } }, ContextCompat.getMainExecutor(this)); @@ -326,7 +325,7 @@ public class TakePhotoActivity extends AppCompatActivity { }); } catch (Exception e) { Log.e(TAG, "error while taking picture", e); - Toast.makeText(this, R.string.take_photo_error_deleting_picture, Toast.LENGTH_SHORT).show(); + Snackbar.make(binding.getRoot(), R.string.take_photo_error_deleting_picture, Snackbar.LENGTH_SHORT).show(); } }); diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt index 38a516c33..65af408a8 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt @@ -37,9 +37,9 @@ import android.view.MotionEvent import android.view.View import android.webkit.WebView import android.webkit.WebViewClient -import android.widget.Toast import autodagger.AutoInjector import coil.load +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication @@ -263,7 +263,7 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(browserIntent) } else { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() Log.e(TAG, "locationGeoLink was null or empty") } } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt index e61b6704b..72c32d348 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt @@ -32,12 +32,11 @@ import android.view.MotionEvent import android.view.View import android.webkit.WebView import android.webkit.WebViewClient -import android.widget.Toast import androidx.appcompat.content.res.AppCompatResources import autodagger.AutoInjector import coil.load import com.google.android.flexbox.FlexboxLayout -import com.nextcloud.android.common.ui.theme.utils.ColorRole +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication @@ -45,6 +44,7 @@ import com.nextcloud.talk.databinding.ItemCustomOutcomingLocationMessageBinding import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.chat.ReadStatus import com.nextcloud.talk.ui.theme.ViewThemeUtils +import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DateUtils import com.nextcloud.talk.utils.UriUtils @@ -249,7 +249,7 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(browserIntent) } else { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() Log.e(TAG, "locationGeoLink was null or empty") } } diff --git a/app/src/main/java/com/nextcloud/talk/callnotification/CallNotificationActivity.kt b/app/src/main/java/com/nextcloud/talk/callnotification/CallNotificationActivity.kt index dfcbd511a..eb5da933a 100644 --- a/app/src/main/java/com/nextcloud/talk/callnotification/CallNotificationActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/callnotification/CallNotificationActivity.kt @@ -30,11 +30,11 @@ import android.os.Handler import android.os.Looper import android.util.Log import android.view.View -import android.widget.Toast import androidx.annotation.RequiresApi import androidx.core.app.NotificationManagerCompat import androidx.lifecycle.ViewModelProvider import autodagger.AutoInjector +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.activities.CallActivity import com.nextcloud.talk.activities.CallBaseActivity @@ -210,7 +210,7 @@ class CallNotificationActivity : CallBaseActivity() { } is CallNotificationViewModel.GetRoomErrorState -> { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding!!.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } else -> {} diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 23bffe15e..8acd7ef1c 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -83,7 +83,6 @@ import android.widget.RelativeLayout.BELOW import android.widget.RelativeLayout.LayoutParams import android.widget.SeekBar import android.widget.TextView -import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AlertDialog import androidx.appcompat.view.ContextThemeWrapper @@ -114,6 +113,7 @@ import coil.transform.CircleCropTransformation import com.google.android.flexbox.FlexboxLayout import com.google.android.material.button.MaterialButton import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R @@ -348,6 +348,7 @@ class ChatActivity : AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT ) + private var voiceRecordDuration = 0L // messy workaround for a mediaPlayer bug, don't delete private var lastRecordMediaPosition: Int = 0 @@ -568,7 +569,7 @@ class ChatActivity : } is ChatViewModel.GetRoomErrorState -> { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } else -> {} @@ -612,7 +613,7 @@ class ChatActivity : } is ChatViewModel.JoinRoomErrorState -> { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } else -> {} @@ -1003,7 +1004,11 @@ class ChatActivity : @SuppressLint("ClickableViewAccessibility") private fun initVoiceRecordButton() { if (!isVoiceRecordingLocked) { - showMicrophoneButton(true) + if (binding.messageInputView.messageInput.text!!.isNotEmpty()) { + showMicrophoneButton(false) + } else { + showMicrophoneButton(true) + } } else if (isVoiceRecordingInProgress) { binding.messageInputView.playPauseBtn.visibility = View.GONE binding.messageInputView.seekBar.visibility = View.GONE @@ -1163,13 +1168,13 @@ class ChatActivity : showRecordAudioUi(false) voiceRecordEndTime = System.currentTimeMillis() - val voiceRecordDuration = voiceRecordEndTime - voiceRecordStartTime + voiceRecordDuration = voiceRecordEndTime - voiceRecordStartTime if (voiceRecordDuration < MINIMUM_VOICE_RECORD_DURATION) { Log.d(TAG, "voiceRecordDuration: $voiceRecordDuration") - Toast.makeText( - context, + Snackbar.make( + binding.root, context.getString(R.string.nc_voice_message_hold_to_record_info), - Toast.LENGTH_SHORT + Snackbar.LENGTH_SHORT ).show() stopAndDiscardAudioRecording() return true @@ -1676,16 +1681,16 @@ class ChatActivity : if (conversationUser != null) { runOnUiThread { if (currentConversation?.objectType == ObjectType.ROOM) { - Toast.makeText( - context, + Snackbar.make( + binding.root, context.resources.getString(R.string.switch_to_main_room), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() } else { - Toast.makeText( - context, + Snackbar.make( + binding.root, context.resources.getString(R.string.switch_to_breakout_room), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() } } @@ -1847,7 +1852,7 @@ class ChatActivity : } } catch (e: Exception) { Log.e(TAG, "failed to initialize mediaPlayer", e) - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } } } @@ -2075,6 +2080,7 @@ class ChatActivity : try { start() + Log.d(TAG, "recording started") isVoiceRecordingInProgress = true } catch (e: IllegalStateException) { Log.e(TAG, "start for audio recording failed") @@ -2087,15 +2093,16 @@ class ChatActivity : private fun stopAndSendAudioRecording() { if (isVoiceRecordingInProgress) { stopAudioRecording() + Log.d(TAG, "stopped and sent audio recording") + val uri = Uri.fromFile(File(currentVoiceRecordFile)) + uploadFile(uri.toString(), true) } - - val uri = Uri.fromFile(File(currentVoiceRecordFile)) - uploadFile(uri.toString(), true) } private fun stopAndDiscardAudioRecording() { if (isVoiceRecordingInProgress) { stopAudioRecording() + Log.d(TAG, "stopped and discarded audio recording") } val cachedFile = File(currentVoiceRecordFile) @@ -2109,12 +2116,17 @@ class ChatActivity : recorder?.apply { try { - stop() + Log.d(TAG, "recording stopped with $voiceRecordDuration") + if (voiceRecordDuration > MINIMUM_VOICE_RECORD_TO_STOP) { + stop() + } release() isVoiceRecordingInProgress = false Log.d(TAG, "stopped recorder. isVoiceRecordingInProgress = false") } catch (e: java.lang.IllegalStateException) { error("error while stopping recorder!" + e) + } catch (e: java.lang.RuntimeException) { + error("error while stopping recorder!" + e) } VibrationUtils.vibrateShort(context) @@ -2365,12 +2377,22 @@ class ChatActivity : ) } } catch (e: IllegalStateException) { - Toast.makeText(context, context.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG) - .show() + context.resources?.getString(R.string.nc_upload_failed)?.let { + Snackbar.make( + binding.root, + it, + Snackbar.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() + context.resources?.getString(R.string.nc_upload_failed)?.let { + Snackbar.make( + binding.root, + it, + Snackbar.LENGTH_LONG + ).show() + } Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e) } } @@ -2420,20 +2442,22 @@ class ChatActivity : UploadAndShareFilesWorker.requestStoragePermission(this) } } catch (e: IllegalStateException) { - Toast.makeText( - context, - context.resources?.getString(R.string.nc_upload_failed), - Toast.LENGTH_LONG + Snackbar.make( + binding.root, + R.string.nc_upload_failed, + Snackbar.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() + context.resources?.getString(R.string.nc_upload_failed)?.let { + Snackbar.make( + binding.root, + it, + Snackbar.LENGTH_LONG + ) + .show() + } Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e) } } @@ -2489,28 +2513,28 @@ class ChatActivity : uploadFiles(filesToUpload) } } else { - Toast - .makeText(context, context.getString(R.string.read_storage_no_permission), Toast.LENGTH_LONG) + Snackbar + .make(binding.root, context.getString(R.string.read_storage_no_permission), Snackbar.LENGTH_LONG) .show() } } else if (requestCode == REQUEST_SHARE_FILE_PERMISSION) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { showLocalFilePicker() } else { - Toast.makeText( - context, + Snackbar.make( + binding.root, context.getString(R.string.nc_file_storage_permission), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() } } else if (requestCode == REQUEST_RECORD_AUDIO_PERMISSION) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // do nothing. user will tap on the microphone again if he wants to record audio.. } else { - Toast.makeText( - context, + Snackbar.make( + binding.root, context.getString(R.string.nc_voice_message_missing_audio_permission), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() } } else if (requestCode == REQUEST_READ_CONTACT_PERMISSION) { @@ -2518,20 +2542,20 @@ class ChatActivity : val intent = Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI) startActivityForResult(intent, REQUEST_CODE_SELECT_CONTACT) } else { - Toast.makeText( - context, + Snackbar.make( + binding.root, context.getString(R.string.nc_share_contact_permission), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() } } else if (requestCode == REQUEST_CAMERA_PERMISSION) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - Toast - .makeText(context, context.getString(R.string.camera_permission_granted), Toast.LENGTH_LONG) + Snackbar + .make(binding.root, context.getString(R.string.camera_permission_granted), Snackbar.LENGTH_LONG) .show() } else { - Toast - .makeText(context, context.getString(R.string.take_photo_permission), Toast.LENGTH_LONG) + Snackbar + .make(binding.root, context.getString(R.string.take_photo_permission), Snackbar.LENGTH_LONG) .show() } } @@ -2564,7 +2588,10 @@ class ChatActivity : metaData ) } catch (e: IllegalArgumentException) { - Toast.makeText(context, context.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG).show() + context.resources?.getString(R.string.nc_upload_failed)?.let { + Snackbar.make(binding.root, it, Snackbar.LENGTH_LONG) + .show() + } Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e) } } @@ -3565,7 +3592,7 @@ class ChatActivity : if (conversationUser != null) { val pp = ParticipantPermissions(conversationUser!!, it) if (!pp.canStartCall() && currentConversation?.hasCall == false) { - Toast.makeText(context, R.string.startCallForbidden, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.startCallForbidden, Snackbar.LENGTH_LONG).show() } else { ApplicationWideCurrentRoomHolder.getInstance().isDialing = true val callIntent = getIntentForCall(isVoiceOnlyCall, callWithoutNotification) @@ -3726,7 +3753,7 @@ class ChatActivity : "Deletion of message is skipped because of restrictions by permissions. " + "This method should not have been called!" ) - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } else { var apiVersion = 1 // FIXME Fix API checking with guests? @@ -3751,10 +3778,10 @@ class ChatActivity : override fun onNext(t: ChatOverallSingleMessage) { if (t.ocs!!.meta!!.statusCode == HttpURLConnection.HTTP_ACCEPTED) { - Toast.makeText( - context, + Snackbar.make( + binding.root, R.string.nc_delete_message_leaked_to_matterbridge, - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() } } @@ -3766,7 +3793,7 @@ class ChatActivity : message?.id, e ) - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } override fun onComplete() { @@ -3956,9 +3983,11 @@ class ChatActivity : private fun showMicrophoneButton(show: Boolean) { if (show && CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "voice-message-sharing")) { + Log.d(TAG, "Microphone shown") binding.messageInputView.messageSendButton.visibility = View.GONE binding.messageInputView.recordAudioButton.visibility = View.VISIBLE } else { + Log.d(TAG, "Microphone hidden") binding.messageInputView.messageSendButton.visibility = View.VISIBLE binding.messageInputView.recordAudioButton.visibility = View.GONE } @@ -4126,7 +4155,7 @@ class ChatActivity : override fun onError(e: Throwable) { Log.e(TAG, "error after clicking on user mention chip", e) - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } override fun onComplete() { @@ -4160,7 +4189,7 @@ class ChatActivity : ) File("$outputDir/$videoName$VIDEO_SUFFIX") } catch (e: IOException) { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() Log.e(TAG, "error while creating video file", e) null } @@ -4226,6 +4255,7 @@ class ChatActivity : private const val REQUEST_CODE_SELECT_REMOTE_FILES = 888 private const val OBJECT_MESSAGE: String = "{object}" private const val MINIMUM_VOICE_RECORD_DURATION: Int = 1000 + private const val MINIMUM_VOICE_RECORD_TO_STOP: Int = 200 private const val VOICE_RECORD_CANCEL_SLIDER_X: Int = -50 private const val VOICE_RECORD_LOCK_BUTTON_Y: Int = -130 private const val VOICE_MESSAGE_META_DATA = "{\"messageType\":\"voice-message\"}" diff --git a/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.kt b/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.kt index e9e3dc28f..941b74ffc 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.kt @@ -29,7 +29,6 @@ import android.os.Handler import android.text.TextUtils import android.util.Log import android.view.View -import android.widget.Toast import androidx.work.Data import androidx.work.OneTimeWorkRequest import androidx.work.WorkManager @@ -37,6 +36,7 @@ import autodagger.AutoInjector import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler import com.bluelinelabs.logansquare.LoganSquare +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication @@ -474,7 +474,7 @@ class AccountVerificationController(args: Bundle? = null) : BaseController( } } else { Log.e(TAG, "failed to set active user") - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding!!.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } } } diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt index f4a64a94a..631db4239 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt @@ -39,7 +39,6 @@ import android.view.MenuItem import android.view.View import android.view.View.GONE import android.view.View.VISIBLE -import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.work.Data import androidx.work.OneTimeWorkRequest @@ -50,6 +49,7 @@ import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.bottomsheets.BottomSheet import com.afollestad.materialdialogs.datetime.dateTimePicker import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.talk.R import com.nextcloud.talk.activities.BaseActivity @@ -594,12 +594,15 @@ class ConversationInfoActivity : } override fun onNext(genericOverall: GenericOverall) { - Toast.makeText(context, context.getString(R.string.nc_clear_history_success), Toast.LENGTH_LONG) - .show() + Snackbar.make( + binding.root, + context.getString(R.string.nc_clear_history_success), + Snackbar.LENGTH_LONG + ).show() } override fun onError(e: Throwable) { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() Log.e(TAG, "failed to clear chat history", e) } diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfo/GuestAccessHelper.kt b/app/src/main/java/com/nextcloud/talk/conversationinfo/GuestAccessHelper.kt index 5377a8dbd..4ec42f0ea 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfo/GuestAccessHelper.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfo/GuestAccessHelper.kt @@ -4,9 +4,9 @@ import android.content.Intent import android.util.Log import android.view.LayoutInflater import android.view.View -import android.widget.Toast import androidx.appcompat.app.AlertDialog import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.ActivityConversationInfoBinding @@ -145,14 +145,17 @@ class GuestAccessHelper( override fun onError(e: Throwable) { val message = context.getString(R.string.nc_guest_access_resend_invitations_failed) - Toast.makeText(context, message, Toast.LENGTH_SHORT).show() + Snackbar.make(binding.root, message, Snackbar.LENGTH_SHORT).show() Log.e(TAG, message, e) } override fun onComplete() { if (resendInvitationsResult.successful) { - Toast.makeText(context, R.string.nc_guest_access_resend_invitations_successful, Toast.LENGTH_SHORT) - .show() + Snackbar.make( + binding.root, + R.string.nc_guest_access_resend_invitations_successful, + Snackbar.LENGTH_SHORT + ).show() } } } @@ -167,7 +170,7 @@ class GuestAccessHelper( override fun onError(e: Throwable) { val message = context.getString(R.string.nc_guest_access_allow_failed) - Toast.makeText(context, message, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, message, Snackbar.LENGTH_LONG).show() Log.e(TAG, message, e) } @@ -210,7 +213,7 @@ class GuestAccessHelper( override fun onError(e: Throwable) { val message = context.getString(R.string.nc_guest_access_password_failed) - Toast.makeText(context, message, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, message, Snackbar.LENGTH_LONG).show() Log.e(TAG, message, e) } diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt index 1316655e1..6329b570d 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt @@ -31,12 +31,12 @@ import android.util.Log import android.view.Menu import android.view.MenuItem import android.view.View -import android.widget.Toast import androidx.core.net.toFile import androidx.core.view.ViewCompat import androidx.lifecycle.ViewModelProvider import autodagger.AutoInjector import com.github.dhaval2404.imagepicker.ImagePicker +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.api.NcApi @@ -141,7 +141,7 @@ class ConversationInfoEditActivity : } is ConversationInfoEditViewModel.GetRoomErrorState -> { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } is ConversationInfoEditViewModel.UploadAvatarSuccessState -> { @@ -150,7 +150,7 @@ class ConversationInfoEditActivity : } is ConversationInfoEditViewModel.UploadAvatarErrorState -> { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } is ConversationInfoEditViewModel.DeleteAvatarSuccessState -> { @@ -159,7 +159,7 @@ class ConversationInfoEditActivity : } is ConversationInfoEditViewModel.DeleteAvatarErrorState -> { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } else -> {} @@ -249,10 +249,10 @@ class ConversationInfoEditActivity : } override fun onError(e: Throwable) { - Toast.makeText( - applicationContext, + Snackbar.make( + binding.root, context.getString(R.string.default_error_msg), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() Log.e(TAG, "Error while saving conversation name", e) } @@ -289,10 +289,10 @@ class ConversationInfoEditActivity : } override fun onError(e: Throwable) { - Toast.makeText( - applicationContext, + Snackbar.make( + binding.root, context.getString(R.string.default_error_msg), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() Log.e(TAG, "Error while saving conversation description", e) } @@ -315,7 +315,7 @@ class ConversationInfoEditActivity : } ImagePicker.RESULT_ERROR -> { - Toast.makeText(this, ImagePicker.getError(data), Toast.LENGTH_SHORT).show() + Snackbar.make(binding.root, ImagePicker.getError(data), Snackbar.LENGTH_SHORT).show() } else -> { diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 1bda26f81..ce2766d6a 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -50,7 +50,6 @@ import android.view.MotionEvent import android.view.View import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputMethodManager -import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.SearchView @@ -68,6 +67,7 @@ import coil.transform.CircleCropTransformation import com.google.android.material.appbar.AppBarLayout import com.google.android.material.button.MaterialButton import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.talk.R import com.nextcloud.talk.activities.BaseActivity @@ -267,7 +267,7 @@ class ConversationsListActivity : fetchRooms() } else { Log.e(TAG, "userManager.currentUser.blockingGet() returned null") - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } showSearchOrToolbar() @@ -309,7 +309,7 @@ class ConversationsListActivity : ) } else { Log.e(TAG, "currentUser was null in loadUserAvatar") - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } } @@ -956,9 +956,11 @@ class ConversationsListActivity : selectedMessageId = messageItem.messageEntry.messageId showConversationByToken(conversationToken) } + LoadMoreResultsItem.VIEW_TYPE -> { loadMoreMessages() } + ConversationItem.VIEW_TYPE -> { handleConversation((Objects.requireNonNull(item) as ConversationItem).model) } @@ -989,14 +991,14 @@ class ConversationsListActivity : ) { handleSharedData() } else { - Toast.makeText(context, R.string.send_to_forbidden, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.send_to_forbidden, Snackbar.LENGTH_LONG).show() } } else if (forwardMessage) { if (hasChatPermission && !isReadOnlyConversation(selectedConversation!!)) { openConversation(intent.getStringExtra(KEY_FORWARD_MSG_TEXT)) forwardMessage = false } else { - Toast.makeText(context, R.string.send_to_forbidden, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.send_to_forbidden, Snackbar.LENGTH_LONG).show() } } else { openConversation() @@ -1023,8 +1025,8 @@ class ConversationsListActivity : } else if (filesToShare != null && filesToShare!!.isNotEmpty()) { showSendFilesConfirmDialog() } else { - Toast - .makeText(context, context.resources.getString(R.string.nc_common_error_sorry), Toast.LENGTH_LONG) + Snackbar + .make(binding.root, context.resources.getString(R.string.nc_common_error_sorry), Snackbar.LENGTH_LONG) .show() } } @@ -1125,18 +1127,18 @@ class ConversationsListActivity : } } if (filesToShare!!.isEmpty() && textToPaste!!.isEmpty()) { - Toast.makeText( - context, + Snackbar.make( + binding.root, context.resources.getString(R.string.nc_common_error_sorry), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() Log.e(TAG, "failed to get data from intent") } } catch (e: Exception) { - Toast.makeText( - context, + Snackbar.make( + binding.root, context.resources.getString(R.string.nc_common_error_sorry), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() Log.e(TAG, "Something went wrong when extracting data from intent") } @@ -1146,10 +1148,10 @@ class ConversationsListActivity : private fun upload() { if (selectedConversation == null) { - Toast.makeText( - context, + Snackbar.make( + binding.root, context.resources.getString(R.string.nc_common_error_sorry), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() Log.e(TAG, "not able to upload any files because conversation was null.") return @@ -1164,21 +1166,25 @@ class ConversationsListActivity : ) } } catch (e: IllegalArgumentException) { - Toast.makeText(context, context.resources.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, context.resources.getString(R.string.nc_upload_failed), Snackbar.LENGTH_LONG) + .show() Log.e(TAG, "Something went wrong when trying to upload file", e) } } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) - if (requestCode == UploadAndShareFilesWorker.REQUEST_PERMISSION && - grantResults.isNotEmpty() && - grantResults[0] == PackageManager.PERMISSION_GRANTED - ) { - Log.d(TAG, "upload starting after permissions were granted") - showSendFilesConfirmDialog() - } else { - Toast.makeText(context, context.getString(R.string.read_storage_no_permission), Toast.LENGTH_LONG).show() + if (requestCode == UploadAndShareFilesWorker.REQUEST_PERMISSION) { + if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + Log.d(TAG, "upload starting after permissions were granted") + showSendFilesConfirmDialog() + } else { + Snackbar.make( + binding.root, + context.getString(R.string.read_storage_no_permission), + Snackbar.LENGTH_LONG + ).show() + } } } @@ -1186,10 +1192,10 @@ class ConversationsListActivity : if (CallActivity.active && selectedConversation!!.token != ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken ) { - Toast.makeText( - context, + Snackbar.make( + binding.root, context.getString(R.string.restrict_join_other_room_while_call), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() return } @@ -1217,6 +1223,7 @@ class ConversationsListActivity : EventStatus.EventType.CONVERSATION_UPDATE -> if (eventStatus.isAllGood && !isRefreshing) { fetchRooms() } + else -> {} } } @@ -1493,7 +1500,9 @@ class ConversationsListActivity : filterState[FilterConversationFragment.UNREAD] = unread } - fun setFilterableItems(items: MutableList>) { filterableConversationItems = items } + fun setFilterableItems(items: MutableList>) { + filterableConversationItems = items + } fun updateFilterConversationButtonColor() { if (filterState.containsValue(true)) { diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt index b5d796b04..59a5a441a 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt +++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt @@ -23,10 +23,12 @@ */ package com.nextcloud.talk.jobs +import android.Manifest import android.app.Notification import android.app.PendingIntent import android.content.Context import android.content.Intent +import android.content.pm.PackageManager import android.graphics.Bitmap import android.media.AudioAttributes import android.media.MediaPlayer @@ -40,7 +42,8 @@ import android.service.notification.StatusBarNotification import android.text.TextUtils import android.util.Base64 import android.util.Log -import android.widget.Toast +import android.view.View +import androidx.core.app.ActivityCompat import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.app.Person @@ -53,6 +56,7 @@ import androidx.work.Worker import androidx.work.WorkerParameters import autodagger.AutoInjector import com.bluelinelabs.logansquare.LoganSquare +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R import com.nextcloud.talk.activities.MainActivity @@ -325,7 +329,11 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor Log.e(TAG, "Failed to get NC notification", e) if (BuildConfig.DEBUG) { Handler(Looper.getMainLooper()).post { - Toast.makeText(context, "Failed to get NC notification", Toast.LENGTH_LONG).show() + Snackbar.make( + View(applicationContext), + "Failed to get NC notification", + Snackbar.LENGTH_LONG + ).show() } } } @@ -734,6 +742,18 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor private fun sendNotification(notificationId: Int, notification: Notification) { Log.d(TAG, "show notification with id $notificationId") + if (ActivityCompat.checkSelfPermission( + applicationContext, + Manifest.permission.POST_NOTIFICATIONS + ) != PackageManager.PERMISSION_GRANTED + ) { + // here to request the missing permissions, and then overriding + // public void onRequestPermissionsResult(int requestCode, String[] permissions, + // int[] grantResults) + // to handle the case where the user grants the permission. See the documentation + // for ActivityCompat#requestPermissions for more details. + return + } notificationManager.notify(notificationId, notification) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -902,6 +922,18 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor .build() val notificationId: Int = SystemClock.uptimeMillis().toInt() + if (ActivityCompat.checkSelfPermission( + applicationContext, + Manifest.permission.POST_NOTIFICATIONS + ) != PackageManager.PERMISSION_GRANTED + ) { + // here to request the missing permissions, and then overriding + // public void onRequestPermissionsResult(int requestCode, String[] permissions, + // int[] grantResults) + // to handle the case where the user grants the permission. See the documentation + // for ActivityCompat#requestPermissions for more details. + return + } notificationManager.notify(notificationId, notification) Log.d(TAG, "'you missed a call' notification was created") } diff --git a/app/src/main/java/com/nextcloud/talk/location/GeocodingActivity.kt b/app/src/main/java/com/nextcloud/talk/location/GeocodingActivity.kt index 535356699..854d3825c 100644 --- a/app/src/main/java/com/nextcloud/talk/location/GeocodingActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/location/GeocodingActivity.kt @@ -32,11 +32,11 @@ import android.view.Menu import android.view.MenuItem import android.view.inputmethod.EditorInfo import android.widget.AdapterView -import android.widget.Toast import androidx.appcompat.widget.SearchView import androidx.core.view.MenuItemCompat import androidx.preference.PreferenceManager import autodagger.AutoInjector +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.adapters.GeocodingAdapter @@ -216,7 +216,7 @@ class GeocodingActivity : } } catch (e: Exception) { Log.e(TAG, "Failed to get geocoded addresses", e) - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } updateResultsOnMainThread(results) } diff --git a/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt b/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt index fef8a16ab..be2bba066 100644 --- a/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt @@ -40,7 +40,6 @@ import android.view.Menu import android.view.MenuItem import android.view.View import android.view.inputmethod.EditorInfo -import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.appcompat.widget.SearchView import androidx.core.content.PermissionChecker @@ -48,6 +47,7 @@ import androidx.core.content.res.ResourcesCompat import androidx.core.view.MenuItemCompat import androidx.preference.PreferenceManager import autodagger.AutoInjector +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.api.NcApi @@ -319,7 +319,11 @@ class LocationPickerActivity : binding.centerMapButton.setOnClickListener { if (myLocation.latitude == COORDINATE_ZERO && myLocation.longitude == COORDINATE_ZERO) { - Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show() + Snackbar.make( + binding.root, + context.getString(R.string.nc_location_unknown), + Snackbar.LENGTH_LONG + ).show() } else { mapController.animateTo(myLocation) moveToCurrentLocation = true @@ -341,11 +345,13 @@ class LocationPickerActivity : setLocationDescription(isGpsLocation = true, isGeocodedResult = false) moveToCurrentLocation = false } + geocodingResult != null -> { binding.shareLocation.isClickable = true setLocationDescription(isGpsLocation = false, isGeocodedResult = true) geocodingResult = null } + else -> { binding.shareLocation.isClickable = true setLocationDescription(isGpsLocation = false, isGeocodedResult = false) @@ -377,6 +383,7 @@ class LocationPickerActivity : this ) } + locationManager!!.isProviderEnabled(LocationManager.GPS_PROVIDER) -> { locationManager!!.requestLocationUpdates( LocationManager.GPS_PROVIDER, @@ -386,6 +393,7 @@ class LocationPickerActivity : ) Log.d(TAG, "LocationManager.NETWORK_PROVIDER falling back to LocationManager.GPS_PROVIDER") } + else -> { Log.e( TAG, @@ -393,16 +401,16 @@ class LocationPickerActivity : " and there is no alternative like UnifiedNlp installed. Furthermore no GPS is " + "supported." ) - Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG) + Snackbar.make(binding.root, context.getString(R.string.nc_location_unknown), Snackbar.LENGTH_LONG) .show() } } } catch (e: SecurityException) { Log.e(TAG, "Error when requesting location updates. Permissions may be missing.", e) - Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, context.getString(R.string.nc_location_unknown), Snackbar.LENGTH_LONG).show() } catch (e: Exception) { Log.e(TAG, "Error when requesting location updates.", e) - Toast.makeText(context, context.getString(R.string.nc_common_error_sorry), Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, context.getString(R.string.nc_common_error_sorry), Snackbar.LENGTH_LONG).show() } } @@ -413,11 +421,13 @@ class LocationPickerActivity : binding.placeName.visibility = View.GONE binding.placeName.text = "" } + isGeocodedResult -> { binding.shareLocationDescription.text = context!!.getText(R.string.nc_share_this_location) binding.placeName.visibility = View.VISIBLE binding.placeName.text = geocodingResult?.displayName } + else -> { binding.shareLocationDescription.text = context!!.getText(R.string.nc_share_this_location) binding.placeName.visibility = View.GONE @@ -476,7 +486,7 @@ class LocationPickerActivity : override fun onError(e: Throwable) { Log.e(TAG, "error when trying to share location", e) - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() finish() } @@ -531,8 +541,11 @@ class LocationPickerActivity : if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE && areAllGranted(grantResults)) { initMap() } else { - Toast.makeText(context, context!!.getString(R.string.nc_location_permission_required), Toast.LENGTH_LONG) - .show() + Snackbar.make( + binding.root, + context!!.getString(R.string.nc_location_permission_required), + Snackbar.LENGTH_LONG + ).show() } } @@ -556,7 +569,7 @@ class LocationPickerActivity : address = nominatimClient!!.getAddress(lon, lat) } catch (e: Exception) { Log.e(TAG, "Failed to get geocoded addresses", e) - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } updateResultOnMainThread(lat, lon, address?.displayName) } diff --git a/app/src/main/java/com/nextcloud/talk/messagesearch/MessageSearchActivity.kt b/app/src/main/java/com/nextcloud/talk/messagesearch/MessageSearchActivity.kt index a4f8373c6..65850c5fa 100644 --- a/app/src/main/java/com/nextcloud/talk/messagesearch/MessageSearchActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/messagesearch/MessageSearchActivity.kt @@ -30,11 +30,11 @@ import android.text.TextUtils import android.view.Menu import android.view.MenuItem import android.view.View -import android.widget.Toast import androidx.activity.OnBackPressedCallback import androidx.appcompat.widget.SearchView import androidx.lifecycle.ViewModelProvider import autodagger.AutoInjector +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.adapters.items.LoadMoreResultsItem @@ -127,7 +127,7 @@ class MessageSearchActivity : BaseActivity() { private fun showError() { displayLoading(false) - Toast.makeText(this, "Error while searching", Toast.LENGTH_SHORT).show() + Snackbar.make(binding.root, "Error while searching", Snackbar.LENGTH_SHORT).show() } private fun showLoading() { diff --git a/app/src/main/java/com/nextcloud/talk/openconversations/ListOpenConversationsActivity.kt b/app/src/main/java/com/nextcloud/talk/openconversations/ListOpenConversationsActivity.kt index 6f1eefd83..aa1b19c97 100644 --- a/app/src/main/java/com/nextcloud/talk/openconversations/ListOpenConversationsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/openconversations/ListOpenConversationsActivity.kt @@ -24,9 +24,9 @@ import android.content.Intent import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.View -import android.widget.Toast import androidx.lifecycle.ViewModelProvider import autodagger.AutoInjector +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.api.NcApi @@ -112,7 +112,7 @@ class ListOpenConversationsActivity : BaseActivity() { binding.emptyList.emptyListViewText.visibility = View.VISIBLE } is OpenConversationsViewModel.FetchConversationsErrorState -> { - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } else -> {} } diff --git a/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt b/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt index ed7c1ce4c..16d8bf67e 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt @@ -30,12 +30,12 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.EditText -import android.widget.Toast import androidx.fragment.app.DialogFragment import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import autodagger.AutoInjector import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.databinding.DialogPollCreateBinding @@ -172,7 +172,7 @@ class PollCreateDialogFragment : DialogFragment(), PollCreateOptionsItemListener private fun showError() { dismiss() Log.e(TAG, "Failed to create poll") - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } override fun onRemoveOptionsItemClick(pollCreateOptionItem: PollCreateOptionItem, position: Int) { diff --git a/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt b/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt index 2ce3ccbf4..2443abaca 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt @@ -32,12 +32,12 @@ import android.widget.CheckBox import android.widget.CompoundButton import android.widget.LinearLayout import android.widget.RadioButton -import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import autodagger.AutoInjector import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.databinding.DialogPollVoteBinding @@ -94,10 +94,10 @@ class PollVoteFragment : Fragment() { PollVoteViewModel.InitialState -> {} is PollVoteViewModel.PollVoteFailedState -> { Log.e(TAG, "Failed to vote on poll.") - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } is PollVoteViewModel.PollVoteHiddenSuccessState -> { - Toast.makeText(context, R.string.polls_voted_hidden_success, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.polls_voted_hidden_success, Snackbar.LENGTH_LONG).show() parentViewModel.dismissDialog() } is PollVoteViewModel.PollVoteSuccessState -> { @@ -182,7 +182,7 @@ class PollVoteFragment : Fragment() { viewModel.selectOption(index, false) } else { checkBox.isChecked = false - Toast.makeText(context, R.string.polls_max_votes_reached, Toast.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.polls_max_votes_reached, Snackbar.LENGTH_LONG).show() } } else { viewModel.deSelectOption(index) diff --git a/app/src/main/java/com/nextcloud/talk/profile/ProfileActivity.kt b/app/src/main/java/com/nextcloud/talk/profile/ProfileActivity.kt index e54e8d469..c44c50cff 100644 --- a/app/src/main/java/com/nextcloud/talk/profile/ProfileActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/profile/ProfileActivity.kt @@ -40,7 +40,6 @@ import android.view.Menu import android.view.MenuItem import android.view.View import android.view.ViewGroup -import android.widget.Toast import androidx.annotation.DrawableRes import androidx.core.content.ContextCompat import androidx.core.net.toFile @@ -49,6 +48,7 @@ import androidx.recyclerview.widget.RecyclerView import autodagger.AutoInjector import com.github.dhaval2404.imagepicker.ImagePicker import com.github.dhaval2404.imagepicker.ImagePicker.Companion.getError +import com.google.android.material.snackbar.Snackbar import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.talk.R import com.nextcloud.talk.activities.BaseActivity @@ -459,13 +459,13 @@ class ProfileActivity : BaseActivity() { override fun onError(e: Throwable) { item.text = userInfo?.getValueByField(item.field) - Toast.makeText( - applicationContext, + Snackbar.make( + binding.root, String.format( resources!!.getString(R.string.failed_to_save), item.field ), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() adapter!!.updateFilteredList() adapter!!.notifyDataSetChanged() @@ -492,8 +492,8 @@ class ProfileActivity : BaseActivity() { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { pickImage.takePicture() } else { - Toast - .makeText(context, context.getString(R.string.take_photo_permission), Toast.LENGTH_LONG) + Snackbar + .make(binding.root, context.getString(R.string.take_photo_permission), Snackbar.LENGTH_LONG) .show() } } @@ -510,7 +510,7 @@ class ProfileActivity : BaseActivity() { ) { uploadAvatar(it.toFile()) } } ImagePicker.RESULT_ERROR -> { - Toast.makeText(this, getError(data), Toast.LENGTH_SHORT).show() + Snackbar.make(binding.root, getError(data), Snackbar.LENGTH_SHORT).show() } else -> { Log.i(TAG, "Task Cancelled") @@ -550,10 +550,10 @@ class ProfileActivity : BaseActivity() { } override fun onError(e: Throwable) { - Toast.makeText( - applicationContext, + Snackbar.make( + binding.root, context.getString(R.string.default_error_msg), - Toast + Snackbar .LENGTH_LONG ).show() Log.e(TAG, "Error uploading avatar", e) diff --git a/app/src/main/java/com/nextcloud/talk/receivers/ShareRecordingToChatReceiver.kt b/app/src/main/java/com/nextcloud/talk/receivers/ShareRecordingToChatReceiver.kt index dd52c63b5..11f6c5bf3 100644 --- a/app/src/main/java/com/nextcloud/talk/receivers/ShareRecordingToChatReceiver.kt +++ b/app/src/main/java/com/nextcloud/talk/receivers/ShareRecordingToChatReceiver.kt @@ -25,8 +25,9 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log -import android.widget.Toast +import android.view.View import autodagger.AutoInjector +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication @@ -91,12 +92,12 @@ class ShareRecordingToChatReceiver : BroadcastReceiver() { // combined with addNextIntentWithParentStack. For further reading, see // https://developer.android.com/develop/ui/views/notifications/navigation#DirectEntry // As we are using the conductor framework it might be hard the combine this or to keep an overview. - // For this reason there is only a toast for now until we got rid of conductor. + // For this reason there is only a Snackbar for now until we got rid of conductor. - Toast.makeText( - context, + Snackbar.make( + View(context), context.resources.getString(R.string.nc_all_ok_operation), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() } diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index fc7a796f6..acf24792b 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -52,7 +52,6 @@ import android.view.View import android.view.WindowManager import android.widget.EditText import android.widget.LinearLayout -import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.view.ContextThemeWrapper import androidx.core.content.ContextCompat @@ -63,6 +62,7 @@ import androidx.work.WorkManager import autodagger.AutoInjector import com.afollestad.materialdialogs.utils.MDUtil.getStringArray import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar import com.google.android.material.textfield.TextInputLayout import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.talk.BuildConfig @@ -471,7 +471,7 @@ class SettingsActivity : BaseActivity() { private fun removeCurrentAccount() { val otherUserExists = userManager.scheduleUserForDeletionWithId(currentUser!!.id!!).blockingGet() val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java).build() - WorkManager.getInstance(this).enqueue(accountRemovalWork) + WorkManager.getInstance(applicationContext).enqueue(accountRemovalWork) if (otherUserExists) { // TODO: find better solution once Conductor is removed finish() @@ -888,10 +888,10 @@ class SettingsActivity : BaseActivity() { } else { appPreferences.setPhoneBookIntegration(false) binding.settingsPhoneBookIntegrationSwitch.isChecked = appPreferences.isPhoneBookIntegrationEnabled - Toast.makeText( - context, + Snackbar.make( + binding.root, context.resources.getString(R.string.no_phone_book_integration_due_to_permissions), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() } } @@ -1082,12 +1082,12 @@ class SettingsActivity : BaseActivity() { val statusCode = genericOverall.ocs?.meta?.statusCode if (statusCode == HTTP_CODE) { dialog.dismiss() - Toast.makeText( - context, + Snackbar.make( + binding.root, context.resources.getString( R.string.nc_settings_phone_book_integration_phone_number_dialog_success ), - Toast.LENGTH_LONG + Snackbar.LENGTH_LONG ).show() } else { textInputLayout.helperText = context.resources.getString( diff --git a/app/src/main/java/com/nextcloud/talk/utils/FileViewerUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/FileViewerUtils.kt index a44e3917c..611f6d659 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/FileViewerUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/FileViewerUtils.kt @@ -29,13 +29,13 @@ import android.util.Log import android.view.View import android.widget.ImageView import android.widget.ProgressBar -import android.widget.Toast import androidx.core.content.FileProvider import androidx.emoji2.widget.EmojiTextView import androidx.work.Data import androidx.work.OneTimeWorkRequest import androidx.work.WorkInfo import androidx.work.WorkManager +import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R import com.nextcloud.talk.activities.FullScreenImageActivity import com.nextcloud.talk.activities.FullScreenMediaActivity @@ -122,7 +122,7 @@ class FileViewerUtils(private val context: Context, private val user: User) { "support it, it can't be handled by an external app and there is no link " + "to open it in the nextcloud files app" ) - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(View(context), R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } } @@ -175,7 +175,7 @@ class FileViewerUtils(private val context: Context, private val user: User) { } } else { Log.e(TAG, "can't open file with unknown mimetype") - Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() + Snackbar.make(View(context), R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() } } diff --git a/app/src/main/res/layout/activity_full_screen_media.xml b/app/src/main/res/layout/activity_full_screen_media.xml index a60868913..4d836b517 100644 --- a/app/src/main/res/layout/activity_full_screen_media.xml +++ b/app/src/main/res/layout/activity_full_screen_media.xml @@ -36,7 +36,7 @@ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Dark" /> - Avatarra Kanpoan Dei-ezarpen aurreratuak + Deia ordubetez egon da martxan. Deitu jakinarazpenik gabe Kameraren baimena eman da. Aukeratu kamera berriro. Aukeratu avatarra cloudetik diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 6a9582d6b..f7243bfc0 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -166,7 +166,7 @@ Захист паролем Слабкий пароль Повторно надіслати запрошення - Запрошення не були надіслані через помилку. + Запрошення не було надіслано через помилку, що виникла. Запрошення було розіслано повторно. Поділитися посиланням на бесіду Введіть повідомлення ... diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b1a67bdbc..b3514534b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -376,7 +376,6 @@ How to translate with transifex: Add attachment Recent Backspace - Search emoji Guest access diff --git a/build.gradle b/build.gradle index 474fa06a9..a581e820a 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ buildscript { ext { - kotlinVersion = '1.8.22' + kotlinVersion = '1.9.10' } repositories { @@ -34,7 +34,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.1.0' + classpath 'com.android.tools.build:gradle:8.1.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}" classpath "org.jetbrains.kotlin:kotlin-serialization:${kotlinVersion}" classpath 'com.github.spotbugs.snom:spotbugs-gradle-plugin:5.1.3'