mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
Add InviteFriendFragment
This commit is contained in:
parent
ddf0b027d7
commit
75ea086032
@ -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)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -35,7 +35,7 @@ class NewConversationFragment : BottomSheetDialogFragment(), NewConversationDele
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
replaceFragment(
|
replaceFragment(
|
||||||
fragment = NewConversationHomeFragment().apply { delegate = this@NewConversationFragment },
|
fragment = NewConversationHomeFragment().also { it.delegate = this },
|
||||||
fragmentKey = NewConversationHomeFragment::class.java.simpleName
|
fragmentKey = NewConversationHomeFragment::class.java.simpleName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -44,8 +44,7 @@ class NewConversationFragment : BottomSheetDialogFragment(), NewConversationDele
|
|||||||
val dialog = BottomSheetDialog(requireContext(), R.style.Theme_Session_BottomSheet)
|
val dialog = BottomSheetDialog(requireContext(), R.style.Theme_Session_BottomSheet)
|
||||||
dialog.setOnShowListener {
|
dialog.setOnShowListener {
|
||||||
val bottomSheetDialog = it as BottomSheetDialog
|
val bottomSheetDialog = it as BottomSheetDialog
|
||||||
val parentLayout =
|
val parentLayout = bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
|
||||||
bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
|
|
||||||
parentLayout?.let {
|
parentLayout?.let {
|
||||||
val behaviour = BottomSheetBehavior.from(it)
|
val behaviour = BottomSheetBehavior.from(it)
|
||||||
val layoutParams = it.layoutParams
|
val layoutParams = it.layoutParams
|
||||||
@ -58,15 +57,15 @@ class NewConversationFragment : BottomSheetDialogFragment(), NewConversationDele
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewMessageSelected() {
|
override fun onNewMessageSelected() {
|
||||||
replaceFragment(NewMessageFragment().apply { delegate = this@NewConversationFragment })
|
replaceFragment(NewMessageFragment().also { it.delegate = this })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateGroupSelected() {
|
override fun onCreateGroupSelected() {
|
||||||
replaceFragment(CreateGroupFragment().apply { delegate = this@NewConversationFragment })
|
replaceFragment(CreateGroupFragment().also { it.delegate = this })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onJoinCommunitySelected() {
|
override fun onJoinCommunitySelected() {
|
||||||
replaceFragment(JoinCommunityFragment().apply { delegate = this@NewConversationFragment })
|
replaceFragment(JoinCommunityFragment().also { it.delegate = this })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onContactSelected(address: String) {
|
override fun onContactSelected(address: String) {
|
||||||
@ -81,7 +80,7 @@ class NewConversationFragment : BottomSheetDialogFragment(), NewConversationDele
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onInviteFriend() {
|
override fun onInviteFriend() {
|
||||||
|
replaceFragment(InviteFriendFragment().also { it.delegate = this })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDialogClosePressed() {
|
override fun onDialogClosePressed() {
|
||||||
|
@ -4,6 +4,7 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
@ -51,7 +52,7 @@ class NewConversationHomeFragment : Fragment() {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun NewConversationScreen() {
|
fun NewConversationScreen() {
|
||||||
Column {
|
Column(modifier = Modifier.background(MaterialTheme.colors.surface)) {
|
||||||
AppBar(stringResource(R.string.dialog_new_conversation_title), onClose = { delegate.onDialogClosePressed() })
|
AppBar(stringResource(R.string.dialog_new_conversation_title), onClose = { delegate.onDialogClosePressed() })
|
||||||
ItemButton(textId = R.string.messageNew, icon = R.drawable.ic_message) { delegate.onNewMessageSelected() }
|
ItemButton(textId = R.string.messageNew, icon = R.drawable.ic_message) { delegate.onNewMessageSelected() }
|
||||||
Divider(modifier = Modifier.padding(start = 80.dp))
|
Divider(modifier = Modifier.padding(start = 80.dp))
|
||||||
|
@ -30,6 +30,8 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.filterIsInstance
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.session.libsession.utilities.Address
|
import org.session.libsession.utilities.Address
|
||||||
@ -61,10 +63,8 @@ class NewMessageFragment : Fragment() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
viewModel.event.collect {
|
viewModel.event.filterIsInstance<Event.Success>().collect {
|
||||||
when (it) {
|
createPrivateChat(it.key)
|
||||||
is Event.Success -> createPrivateChat(it.key)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ private fun NewMessage(
|
|||||||
) {
|
) {
|
||||||
val pagerState = rememberPagerState { TITLES.size }
|
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() })
|
AppBar(stringResource(R.string.messageNew), onClose = { onClose() }, onBack = { onBack() })
|
||||||
SessionTabRow(pagerState, TITLES)
|
SessionTabRow(pagerState, TITLES)
|
||||||
HorizontalPager(pagerState) {
|
HorizontalPager(pagerState) {
|
||||||
|
@ -42,6 +42,7 @@ import org.thoughtcrime.securesms.ui.SessionShieldIcon
|
|||||||
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
|
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
|
||||||
import org.thoughtcrime.securesms.ui.classicDarkColors
|
import org.thoughtcrime.securesms.ui.classicDarkColors
|
||||||
import org.thoughtcrime.securesms.ui.colorDestructive
|
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.OutlineButton
|
||||||
import org.thoughtcrime.securesms.ui.components.QrImage
|
import org.thoughtcrime.securesms.ui.components.QrImage
|
||||||
import org.thoughtcrime.securesms.ui.components.SmallButtons
|
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.recoveryPasswordHideRecoveryPassword), style = MaterialTheme.typography.h8)
|
||||||
Text(text = stringResource(R.string.recoveryPasswordHideRecoveryPasswordDescription))
|
Text(text = stringResource(R.string.recoveryPasswordHideRecoveryPasswordDescription))
|
||||||
}
|
}
|
||||||
CompositionLocalProvider(
|
DestructiveButtons {
|
||||||
LocalButtonColor provides colorDestructive,
|
|
||||||
) {
|
|
||||||
OutlineButton(
|
OutlineButton(
|
||||||
textId = R.string.hide,
|
textId = R.string.hide,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -3,8 +3,6 @@ package org.thoughtcrime.securesms.preferences
|
|||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.ClipData
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
@ -353,32 +351,6 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
}
|
}
|
||||||
.execute()
|
.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
|
// endregion
|
||||||
|
|
||||||
private inner class DisplayNameEditActionModeCallback: ActionMode.Callback {
|
private inner class DisplayNameEditActionModeCallback: ActionMode.Callback {
|
||||||
@ -420,7 +392,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
) {
|
) {
|
||||||
OutlineButton(
|
OutlineButton(
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
onClick = ::sharePublicKey
|
onClick = { sendInvitation() }
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.share))
|
Text(stringResource(R.string.share))
|
||||||
}
|
}
|
||||||
@ -499,4 +471,4 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
|
|
||||||
fun createReceiver(update: () -> Unit) = object : BroadcastReceiver() {
|
fun createReceiver(update: () -> Unit) = object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) { update() }
|
override fun onReceive(context: Context, intent: Intent) { update() }
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
}
|
@ -80,6 +80,7 @@ import org.session.libsession.utilities.recipients.Recipient
|
|||||||
import org.session.libsession.utilities.runIf
|
import org.session.libsession.utilities.runIf
|
||||||
import org.thoughtcrime.securesms.components.ProfilePictureView
|
import org.thoughtcrime.securesms.components.ProfilePictureView
|
||||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.OptionsCard
|
import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.OptionsCard
|
||||||
|
import org.thoughtcrime.securesms.ui.components.OnPrimaryButtons
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@ -219,7 +220,7 @@ fun CellWithPaddingAndMargin(
|
|||||||
margin: Dp = 32.dp,
|
margin: Dp = 32.dp,
|
||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
CompositionLocalProvider(LocalButtonColor provides MaterialTheme.colors.onPrimary) {
|
OnPrimaryButtons {
|
||||||
Card(
|
Card(
|
||||||
backgroundColor = LocalCellColor.current,
|
backgroundColor = LocalCellColor.current,
|
||||||
shape = RoundedCornerShape(16.dp),
|
shape = RoundedCornerShape(16.dp),
|
||||||
|
@ -172,3 +172,8 @@ fun SmallButtons(content: @Composable () -> Unit) {
|
|||||||
fun DestructiveButtons(content: @Composable () -> Unit) {
|
fun DestructiveButtons(content: @Composable () -> Unit) {
|
||||||
CompositionLocalProvider(LocalButtonColor provides colorDestructive) { content() }
|
CompositionLocalProvider(LocalButtonColor provides colorDestructive) { content() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun OnPrimaryButtons(content: @Composable () -> Unit) {
|
||||||
|
CompositionLocalProvider(LocalButtonColor provides MaterialTheme.colors.onPrimary) { content() }
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user