Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.components
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.PointF
import android.media.ExifInterface
import android.net.Uri
import android.os.AsyncTask
import android.util.AttributeSet
Expand Down Expand Up @@ -49,8 +50,31 @@ class ZoomingImageView @JvmOverloads constructor(
this.photoView = findViewById(R.id.image_view)

this.subsamplingImageView = findViewById(R.id.subsampling_image_view)
}

private fun getSubsamplingOrientation(context: Context, uri: Uri): Int {
var exifOrientation = ExifInterface.ORIENTATION_UNDEFINED
try {
PartAuthority.getAttachmentStream(context, uri).use { input ->
val exif = ExifInterface(input)
exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED
)
}
} catch (e: Exception) {
Log.w(TAG, "Failed to read EXIF orientation", e)
}

subsamplingImageView.orientation = SubsamplingScaleImageView.ORIENTATION_USE_EXIF
return when (exifOrientation) {
ExifInterface.ORIENTATION_ROTATE_90,
ExifInterface.ORIENTATION_TRANSPOSE -> SubsamplingScaleImageView.ORIENTATION_90
ExifInterface.ORIENTATION_ROTATE_180,
ExifInterface.ORIENTATION_FLIP_VERTICAL -> SubsamplingScaleImageView.ORIENTATION_180
ExifInterface.ORIENTATION_ROTATE_270,
ExifInterface.ORIENTATION_TRANSVERSE -> SubsamplingScaleImageView.ORIENTATION_270
else -> SubsamplingScaleImageView.ORIENTATION_0
}
}

fun setInteractor(interactor: ZoomImageInteractions?) {
Expand All @@ -62,39 +86,33 @@ class ZoomingImageView @JvmOverloads constructor(
val context = context
val maxTextureSize = BitmapUtil.getMaxTextureSize()

Log.i(
TAG,
"Max texture size: $maxTextureSize"
)

object : AsyncTask<Void?, Void?, Pair<Int, Int>?>() {
override fun doInBackground(vararg params: Void?): Pair<Int, Int>? {
object : AsyncTask<Void?, Void?, ImageLoadResult?>() {
override fun doInBackground(vararg params: Void?): ImageLoadResult? {
if (MediaUtil.isGif(contentType)) return null

try {
val inputStream = PartAuthority.getAttachmentStream(context, uri)
return BitmapUtil.getDimensions(inputStream)
} catch (e: IOException) {
Log.w(TAG, e)
return null
} catch (e: BitmapDecodingException) {
val dimStream = PartAuthority.getAttachmentStream(context, uri)
val dimensions = BitmapUtil.getDimensions(dimStream)
val orientation = getSubsamplingOrientation(context, uri)

return ImageLoadResult(dimensions.first, dimensions.second, orientation)
} catch (e: Exception) {
Log.w(TAG, e)
return null
}
}

override fun onPostExecute(dimensions: Pair<Int, Int>?) {
override fun onPostExecute(result: ImageLoadResult?) {
Log.i(
TAG,
"Dimensions: " + (if (dimensions == null) "(null)" else dimensions.first.toString() + ", " + dimensions.second)
"Dimensions: " + (if (result == null) "(null)" else "${result.width} , ${result.height} - orientation: ${result.orientation}")
)

if (dimensions == null || (dimensions.first <= maxTextureSize && dimensions.second <= maxTextureSize)) {
if (result == null || (result.width <= maxTextureSize && result.height <= maxTextureSize)) {
Log.i(TAG, "Loading in standard image view...")
setImageViewUri(glideRequests, uri)
} else {
Log.i(TAG, "Loading in subsampling image view...")
setSubsamplingImageViewUri(uri)
setSubsamplingImageViewUri(uri, result.orientation)
}
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
Expand All @@ -116,13 +134,14 @@ class ZoomingImageView @JvmOverloads constructor(
}

@SuppressLint("ClickableViewAccessibility")
private fun setSubsamplingImageViewUri(uri: Uri) {
private fun setSubsamplingImageViewUri(uri: Uri, orientation: Int) {
subsamplingImageView.setBitmapDecoderFactory(AttachmentBitmapDecoderFactory())
subsamplingImageView.setRegionDecoderFactory(AttachmentRegionDecoderFactory())

subsamplingImageView.visibility = VISIBLE
photoView.visibility = GONE

subsamplingImageView.orientation = orientation

val gestureDetector = GestureDetector(
context,
object : GestureDetector.SimpleOnGestureListener() {
Expand All @@ -132,7 +151,6 @@ class ZoomingImageView @JvmOverloads constructor(
}
}
)

subsamplingImageView.setImage(ImageSource.uri(uri))
subsamplingImageView.setOnTouchListener { v, event ->
gestureDetector.onTouchEvent(event)
Expand All @@ -158,6 +176,8 @@ class ZoomingImageView @JvmOverloads constructor(
}
}

data class ImageLoadResult(val width: Int, val height: Int, val orientation: Int)

companion object {
private val TAG: String = ZoomingImageView::class.java.simpleName
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ import org.session.libsession.messaging.open_groups.OpenGroupApi
import org.session.libsession.messaging.sending_receiving.MessageSender
import org.session.libsession.messaging.sending_receiving.attachments.Attachment
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
import org.session.libsession.snode.SnodeAPI
import org.session.libsession.snode.SnodeClock
Expand Down Expand Up @@ -265,6 +266,7 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
@Inject lateinit var clock: SnodeClock
@Inject lateinit var messageSender: MessageSender
@Inject lateinit var resendMessageUtilities: ResendMessageUtilities
@Inject lateinit var messageNotifier: MessageNotifier
@Inject @ManagerScope
lateinit var scope: CoroutineScope

Expand Down Expand Up @@ -771,12 +773,12 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,

override fun onResume() {
super.onResume()
ApplicationContext.getInstance(this).messageNotifier.setVisibleThread(viewModel.threadId)
messageNotifier.setVisibleThread(viewModel.threadId)
}

override fun onPause() {
super.onPause()
ApplicationContext.getInstance(this).messageNotifier.setVisibleThread(-1)
messageNotifier.setVisibleThread(-1)
}

override fun getSystemService(name: String): Any? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ import org.session.libsession.utilities.recipients.RecipientData
import org.session.libsession.utilities.recipients.displayName
import org.session.libsession.utilities.updateContact
import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.ScreenLockActionBarActivity
import org.thoughtcrime.securesms.auth.LoginStateRepository
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
Expand Down Expand Up @@ -550,7 +549,7 @@ class HomeActivity : ScreenLockActionBarActivity(),

override fun onPause() {
super.onPause()
ApplicationContext.getInstance(this).messageNotifier.setHomeScreenVisible(false)
messageNotifier.setHomeScreenVisible(false)
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
Expand Down
22 changes: 13 additions & 9 deletions app/src/main/java/org/thoughtcrime/securesms/home/HomeDialogs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.squareup.phrase.Phrase
import kotlinx.coroutines.delay
import network.loki.messenger.R
import org.session.libsession.utilities.NonTranslatableStringConstants
import org.session.libsession.utilities.StringSubstitutionConstants
import org.session.libsession.utilities.StringSubstitutionConstants.APP_PRO_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.PRO_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.TIME_KEY
Expand All @@ -22,6 +23,8 @@ import org.thoughtcrime.securesms.ui.AnimatedSessionProCTA
import org.thoughtcrime.securesms.ui.CTAFeature
import org.thoughtcrime.securesms.ui.OpenURLAlertDialog
import org.thoughtcrime.securesms.ui.PinProCTA
import org.thoughtcrime.securesms.ui.SessionProCTA
import org.thoughtcrime.securesms.ui.SimpleSessionProCTA
import org.thoughtcrime.securesms.ui.UserProfileModal
import org.thoughtcrime.securesms.ui.theme.SessionMaterialTheme

Expand Down Expand Up @@ -158,18 +161,19 @@ fun HomeDialogs(

if (showDonation && dialogsState.donationCTA) {
val context = LocalContext.current
AnimatedSessionProCTA(
heroImageBg = R.drawable.cta_hero_generic_bg,
heroImageAnimatedFg = R.drawable.cta_hero_generic_fg,
title = stringResource(R.string.proExpired), //todo DONATION need crowdin strings
SimpleSessionProCTA(
heroImage = R.drawable.cta_hero_flower,
title = Phrase.from(context,R.string.donateSessionHelp)
.put(StringSubstitutionConstants.APP_NAME_KEY, NonTranslatableStringConstants.APP_NAME)
.format()
.toString(),
showProBadge = false,
text = Phrase.from(context,R.string.proExpiredDescription)
.put(PRO_KEY, NonTranslatableStringConstants.PRO)
.put(APP_PRO_KEY, NonTranslatableStringConstants.APP_PRO)
text = Phrase.from(context,R.string.donateSessionDescription)
.put(StringSubstitutionConstants.APP_NAME_KEY, NonTranslatableStringConstants.APP_NAME)
.format()
.toString(),//todo DONATION need crowdin strings
.toString(),
positiveButtonText = stringResource(R.string.donate),
negativeButtonText = stringResource(R.string.cancel), //todo DONATION need crowdin strings
negativeButtonText = stringResource(R.string.maybeLater),
onUpgrade = {
sendCommand(HideDonationCTADialog)
sendCommand(ShowDonationConfirmation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,24 +75,7 @@ import org.thoughtcrime.securesms.home.PathActivity
import org.thoughtcrime.securesms.messagerequests.MessageRequestsActivity
import org.thoughtcrime.securesms.preferences.SettingsViewModel.AvatarDialogState.TempAvatar
import org.thoughtcrime.securesms.preferences.SettingsViewModel.AvatarDialogState.UserAvatar
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.ClearData
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.HideAnimatedProCTA
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.HideAvatarPickerOptions
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.HideClearDataDialog
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.HideSimpleDialog
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.HideUrlDialog
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.HideUsernameDialog
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.OnAvatarDialogDismissed
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.OnDonateClicked
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.RemoveAvatar
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.SaveAvatar
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.SetUsername
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.ShowAnimatedProCTA
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.ShowAvatarDialog
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.ShowClearDataDialog
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.ShowUrlDialog
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.ShowUsernameDialog
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.UpdateUsername
import org.thoughtcrime.securesms.preferences.SettingsViewModel.Commands.*
import org.thoughtcrime.securesms.preferences.appearance.AppearanceSettingsActivity
import org.thoughtcrime.securesms.preferences.prosettings.ProSettingsActivity
import org.thoughtcrime.securesms.pro.ProDataState
Expand Down Expand Up @@ -417,6 +400,8 @@ fun Settings(
if(uiState.showUrlDialog != null){
OpenURLAlertDialog(
url = uiState.showUrlDialog,
onLinkOpened = { sendCommand(OnLinkOpened(uiState.showUrlDialog)) },
onLinkCopied = { sendCommand(OnLinkCopied(uiState.showUrlDialog)) },
onDismissRequest = { sendCommand(HideUrlDialog) }
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,17 @@ import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities.textSi
import org.thoughtcrime.securesms.database.RecipientRepository
import org.thoughtcrime.securesms.dependencies.ConfigFactory
import org.thoughtcrime.securesms.mms.MediaConstraints
import org.thoughtcrime.securesms.pro.ProStatusManager
import org.thoughtcrime.securesms.pro.ProDataState
import org.thoughtcrime.securesms.pro.ProDetailsRepository
import org.thoughtcrime.securesms.pro.ProStatusManager
import org.thoughtcrime.securesms.pro.getDefaultSubscriptionStateData
import org.thoughtcrime.securesms.reviews.InAppReviewManager
import org.thoughtcrime.securesms.ui.SimpleDialogData
import org.thoughtcrime.securesms.util.AnimatedImageUtils
import org.thoughtcrime.securesms.util.AvatarUIData
import org.thoughtcrime.securesms.util.AvatarUtils
import org.thoughtcrime.securesms.util.ClearDataUtils
import org.thoughtcrime.securesms.util.DonationManager
import org.thoughtcrime.securesms.util.DonationManager.Companion.URL_DONATE
import org.thoughtcrime.securesms.util.NetworkConnectivity
import org.thoughtcrime.securesms.util.mapToStateFlow
Expand All @@ -84,6 +85,7 @@ class SettingsViewModel @Inject constructor(
private val avatarUploadManager: AvatarUploadManager,
private val attachmentProcessor: AttachmentProcessor,
private val proDetailsRepository: ProDetailsRepository,
private val donationManager: DonationManager,
) : ViewModel() {
private val TAG = "SettingsViewModel"

Expand Down Expand Up @@ -604,6 +606,20 @@ class SettingsViewModel @Inject constructor(
is Commands.HideSimpleDialog -> {
_uiState.update { it.copy(showSimpleDialog = null) }
}

is Commands.OnLinkOpened -> {
// if the link was for donation, mark it as seen
if(command.url == URL_DONATE) {
donationManager.onDonationSeen()
}
}

is Commands.OnLinkCopied -> {
// if the link was for donation, mark it as seen
if(command.url == URL_DONATE) {
donationManager.onDonationCopied()
}
}
}
}

Expand Down Expand Up @@ -683,5 +699,8 @@ class SettingsViewModel @Inject constructor(
data object OnDonateClicked: Commands

data class ClearData(val clearNetwork: Boolean): Commands

data class OnLinkOpened(val url: String) : Commands
data class OnLinkCopied(val url: String) : Commands
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class DonationManager @Inject constructor(
val prefs: TextSecurePreferences
){
companion object {
const val URL_DONATE = "https://session.foundation/donate#app"
const val URL_DONATE = "https://getsession.org/donate#app"
}

// increment in days between showing the donation CTA, matching the list index to the number of views of the CTA
Expand Down
Binary file added app/src/main/res/drawable/cta_hero_flower.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.