Add InviteFriendFragment

This commit is contained in:
Andrew 2024-05-04 20:07:20 +09:30
parent ddf0b027d7
commit 75ea086032
9 changed files with 171 additions and 47 deletions

View File

@ -0,0 +1,115 @@
package org.thoughtcrime.securesms.conversation.start
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.fragment.app.Fragment
import dagger.hilt.android.AndroidEntryPoint
import network.loki.messenger.R
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.preferences.copyPublicKey
import org.thoughtcrime.securesms.preferences.sendInvitation
import org.thoughtcrime.securesms.ui.AppTheme
import org.thoughtcrime.securesms.ui.classicDarkColors
import org.thoughtcrime.securesms.ui.components.AppBar
import org.thoughtcrime.securesms.ui.components.OnPrimaryButtons
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.SmallButtons
import org.thoughtcrime.securesms.ui.components.TemporaryStateButton
@AndroidEntryPoint
class InviteFriendFragment : Fragment() {
lateinit var delegate: NewConversationDelegate
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View = ComposeView(requireContext()).apply {
setContent {
AppTheme {
InviteFriend()
}
}
}
@Composable
private fun InviteFriend() {
Column(modifier = Modifier.background(MaterialTheme.colors.surface)) {
AppBar("Invite a Friend", onBack = { delegate.onDialogBackPressed() }, onClose = { delegate.onDialogClosePressed() })
Column(
modifier = Modifier.padding(horizontal = 24.dp),
verticalArrangement = spacedBy(10.dp)
) {
Box(
modifier = Modifier
.border(
width = 1.dp,
color = classicDarkColors[5],
shape = RoundedCornerShape(size = 13.dp)
)
.fillMaxWidth()
.wrapContentHeight()
) {
Text(
TextSecurePreferences.getLocalNumber(LocalContext.current)!!,
textAlign = TextAlign.Center,
modifier = Modifier
.align(Alignment.Center)
.padding(22.dp)
)
}
Text(
"Invite your friend to chat with you on Session by sharing your Account ID with them.",
textAlign = TextAlign.Center,
modifier = Modifier.padding(horizontal = 8.dp)
)
OnPrimaryButtons {
SmallButtons {
Row(horizontalArrangement = spacedBy(20.dp)) {
OutlineButton(
modifier = Modifier.weight(1f),
onClick = { requireContext().sendInvitation() }
) {
Text(stringResource(R.string.share))
}
TemporaryStateButton { source, temporary ->
OutlineButton(
modifier = Modifier.weight(1f),
interactionSource = source,
onClick = { requireContext().copyPublicKey() },
) {
AnimatedVisibility(temporary) { Text(stringResource(R.string.copied)) }
AnimatedVisibility(!temporary) { Text(stringResource(R.string.copy)) }
}
}
}
}
}
}
}
}
}

View File

@ -35,7 +35,7 @@ class NewConversationFragment : BottomSheetDialogFragment(), NewConversationDele
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
replaceFragment(
fragment = NewConversationHomeFragment().apply { delegate = this@NewConversationFragment },
fragment = NewConversationHomeFragment().also { it.delegate = this },
fragmentKey = NewConversationHomeFragment::class.java.simpleName
)
}
@ -44,8 +44,7 @@ class NewConversationFragment : BottomSheetDialogFragment(), NewConversationDele
val dialog = BottomSheetDialog(requireContext(), R.style.Theme_Session_BottomSheet)
dialog.setOnShowListener {
val bottomSheetDialog = it as BottomSheetDialog
val parentLayout =
bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
val parentLayout = bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
parentLayout?.let {
val behaviour = BottomSheetBehavior.from(it)
val layoutParams = it.layoutParams
@ -58,15 +57,15 @@ class NewConversationFragment : BottomSheetDialogFragment(), NewConversationDele
}
override fun onNewMessageSelected() {
replaceFragment(NewMessageFragment().apply { delegate = this@NewConversationFragment })
replaceFragment(NewMessageFragment().also { it.delegate = this })
}
override fun onCreateGroupSelected() {
replaceFragment(CreateGroupFragment().apply { delegate = this@NewConversationFragment })
replaceFragment(CreateGroupFragment().also { it.delegate = this })
}
override fun onJoinCommunitySelected() {
replaceFragment(JoinCommunityFragment().apply { delegate = this@NewConversationFragment })
replaceFragment(JoinCommunityFragment().also { it.delegate = this })
}
override fun onContactSelected(address: String) {
@ -81,7 +80,7 @@ class NewConversationFragment : BottomSheetDialogFragment(), NewConversationDele
}
override fun onInviteFriend() {
replaceFragment(InviteFriendFragment().also { it.delegate = this })
}
override fun onDialogClosePressed() {

View File

@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
@ -51,7 +52,7 @@ class NewConversationHomeFragment : Fragment() {
@Composable
fun NewConversationScreen() {
Column {
Column(modifier = Modifier.background(MaterialTheme.colors.surface)) {
AppBar(stringResource(R.string.dialog_new_conversation_title), onClose = { delegate.onDialogClosePressed() })
ItemButton(textId = R.string.messageNew, icon = R.drawable.ic_message) { delegate.onNewMessageSelected() }
Divider(modifier = Modifier.padding(start = 80.dp))

View File

@ -30,6 +30,8 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.launch
import network.loki.messenger.R
import org.session.libsession.utilities.Address
@ -61,10 +63,8 @@ class NewMessageFragment : Fragment() {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
viewModel.event.collect {
when (it) {
is Event.Success -> createPrivateChat(it.key)
}
viewModel.event.filterIsInstance<Event.Success>().collect {
createPrivateChat(it.key)
}
}
}
@ -121,7 +121,7 @@ private fun NewMessage(
) {
val pagerState = rememberPagerState { TITLES.size }
Column(modifier = Modifier.background(MaterialTheme.colors.background)) {
Column(modifier = Modifier.background(MaterialTheme.colors.surface)) {
AppBar(stringResource(R.string.messageNew), onClose = { onClose() }, onBack = { onBack() })
SessionTabRow(pagerState, TITLES)
HorizontalPager(pagerState) {

View File

@ -42,6 +42,7 @@ import org.thoughtcrime.securesms.ui.SessionShieldIcon
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
import org.thoughtcrime.securesms.ui.classicDarkColors
import org.thoughtcrime.securesms.ui.colorDestructive
import org.thoughtcrime.securesms.ui.components.DestructiveButtons
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.QrImage
import org.thoughtcrime.securesms.ui.components.SmallButtons
@ -205,9 +206,7 @@ fun HideRecoveryPasswordCell(onHide: () -> Unit = {}) {
Text(text = stringResource(R.string.recoveryPasswordHideRecoveryPassword), style = MaterialTheme.typography.h8)
Text(text = stringResource(R.string.recoveryPasswordHideRecoveryPasswordDescription))
}
CompositionLocalProvider(
LocalButtonColor provides colorDestructive,
) {
DestructiveButtons {
OutlineButton(
textId = R.string.hide,
modifier = Modifier

View File

@ -3,8 +3,6 @@ package org.thoughtcrime.securesms.preferences
import android.Manifest
import android.app.Activity
import android.content.BroadcastReceiver
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
@ -353,32 +351,6 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
}
.execute()
}
private fun copyPublicKey() {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("Session ID", hexEncodedPublicKey)
clipboard.setPrimaryClip(clip)
Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show()
}
private fun sharePublicKey() {
Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, hexEncodedPublicKey)
type = "text/plain"
}.let { Intent.createChooser(it, getString(R.string.share)) }
.let(::startActivity)
}
private fun sendInvitation() {
Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "Hey, I've been using Session to chat with complete privacy and security. Come join me! Download it at https://getsession.org/. My Session ID is $hexEncodedPublicKey !")
type = "text/plain"
}.let { Intent.createChooser(it, getString(R.string.activity_settings_invite_button_title)) }
.let(::startActivity)
}
// endregion
private inner class DisplayNameEditActionModeCallback: ActionMode.Callback {
@ -420,7 +392,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
) {
OutlineButton(
modifier = Modifier.weight(1f),
onClick = ::sharePublicKey
onClick = { sendInvitation() }
) {
Text(stringResource(R.string.share))
}

View File

@ -0,0 +1,32 @@
package org.thoughtcrime.securesms.preferences
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.widget.Toast
import network.loki.messenger.R
import org.session.libsession.utilities.TextSecurePreferences
fun Context.sendInvitation() {
Intent().apply {
action = Intent.ACTION_SEND
putExtra(
Intent.EXTRA_TEXT,
"""Hey, I've been using Session to chat with complete privacy and security. Come join me! My Account ID is
${TextSecurePreferences.getLocalNumber(this@sendInvitation)}
Download it at https://getsession.org/"""
)
type = "text/plain"
}.let { Intent.createChooser(it, getString(R.string.activity_settings_invite_button_title)) }
.let(::startActivity)
}
fun Context.copyPublicKey() {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("Session ID", TextSecurePreferences.getLocalNumber(this))
clipboard.setPrimaryClip(clip)
Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show()
}

View File

@ -80,6 +80,7 @@ import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.runIf
import org.thoughtcrime.securesms.components.ProfilePictureView
import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.OptionsCard
import org.thoughtcrime.securesms.ui.components.OnPrimaryButtons
import kotlin.math.min
import kotlin.math.roundToInt
@ -219,7 +220,7 @@ fun CellWithPaddingAndMargin(
margin: Dp = 32.dp,
content: @Composable () -> Unit
) {
CompositionLocalProvider(LocalButtonColor provides MaterialTheme.colors.onPrimary) {
OnPrimaryButtons {
Card(
backgroundColor = LocalCellColor.current,
shape = RoundedCornerShape(16.dp),

View File

@ -172,3 +172,8 @@ fun SmallButtons(content: @Composable () -> Unit) {
fun DestructiveButtons(content: @Composable () -> Unit) {
CompositionLocalProvider(LocalButtonColor provides colorDestructive) { content() }
}
@Composable
fun OnPrimaryButtons(content: @Composable () -> Unit) {
CompositionLocalProvider(LocalButtonColor provides MaterialTheme.colors.onPrimary) { content() }
}