Using the Compose version of our QR scanning

Deleting non needed files
This commit is contained in:
ThomasSession 2024-09-05 15:33:33 +10:00 committed by fanchao
parent a7843af306
commit fa90b746b2
9 changed files with 70 additions and 415 deletions

View File

@ -37,6 +37,8 @@ class JoinCommunityFragment : Fragment() {
lateinit var delegate: StartConversationDelegate lateinit var delegate: StartConversationDelegate
var lastUrl: String? = null
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@ -66,34 +68,59 @@ class JoinCommunityFragment : Fragment() {
} }
fun joinCommunityIfPossible(url: String) { fun joinCommunityIfPossible(url: String) {
if(lastUrl == url) return
lastUrl = url
lifecycleScope.launch(Dispatchers.Main) {
val openGroup = try { val openGroup = try {
OpenGroupUrlParser.parseUrl(url) OpenGroupUrlParser.parseUrl(url)
} catch (e: OpenGroupUrlParser.Error) { } catch (e: OpenGroupUrlParser.Error) {
when (e) { when (e) {
is OpenGroupUrlParser.Error.MalformedURL, OpenGroupUrlParser.Error.NoRoom -> { is OpenGroupUrlParser.Error.MalformedURL, OpenGroupUrlParser.Error.NoRoom -> {
return Toast.makeText(activity, context?.resources?.getString(R.string.communityJoinError), Toast.LENGTH_SHORT).show() return@launch Toast.makeText(
activity,
context?.resources?.getString(R.string.communityJoinError),
Toast.LENGTH_SHORT
).show()
} }
is OpenGroupUrlParser.Error.InvalidPublicKey, OpenGroupUrlParser.Error.NoPublicKey -> { is OpenGroupUrlParser.Error.InvalidPublicKey, OpenGroupUrlParser.Error.NoPublicKey -> {
return Toast.makeText(activity, R.string.communityEnterUrlErrorInvalidDescription, Toast.LENGTH_SHORT).show() return@launch Toast.makeText(
activity,
R.string.communityEnterUrlErrorInvalidDescription,
Toast.LENGTH_SHORT
).show()
} }
} }
} }
showLoader() showLoader()
lifecycleScope.launch(Dispatchers.IO) { withContext(Dispatchers.IO) {
try { try {
val sanitizedServer = openGroup.server.removeSuffix("/") val sanitizedServer = openGroup.server.removeSuffix("/")
val openGroupID = "$sanitizedServer.${openGroup.room}" val openGroupID = "$sanitizedServer.${openGroup.room}"
OpenGroupManager.add(sanitizedServer, openGroup.room, openGroup.serverPublicKey, requireContext()) OpenGroupManager.add(
sanitizedServer,
openGroup.room,
openGroup.serverPublicKey,
requireContext()
)
val storage = MessagingModuleConfiguration.shared.storage val storage = MessagingModuleConfiguration.shared.storage
storage.onOpenGroupAdded(sanitizedServer, openGroup.room) storage.onOpenGroupAdded(sanitizedServer, openGroup.room)
val threadID = GroupManager.getOpenGroupThreadID(openGroupID, requireContext()) val threadID =
GroupManager.getOpenGroupThreadID(openGroupID, requireContext())
val groupID = GroupUtil.getEncodedOpenGroupID(openGroupID.toByteArray()) val groupID = GroupUtil.getEncodedOpenGroupID(openGroupID.toByteArray())
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(requireContext()) ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(
requireContext()
)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
val recipient = Recipient.from(requireContext(), Address.fromSerialized(groupID), false) val recipient = Recipient.from(
requireContext(),
Address.fromSerialized(groupID),
false
)
openConversationActivity(requireContext(), threadID, recipient) openConversationActivity(requireContext(), threadID, recipient)
delegate.onDialogClosePressed() delegate.onDialogClosePressed()
} }
@ -101,10 +128,11 @@ class JoinCommunityFragment : Fragment() {
Log.e("Loki", "Couldn't join community.", e) Log.e("Loki", "Couldn't join community.", e)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
hideLoader() hideLoader()
val txt = Phrase.from(context, R.string.groupErrorJoin).put(GROUP_NAME_KEY, url).format().toString() val txt = Phrase.from(context, R.string.groupErrorJoin)
.put(GROUP_NAME_KEY, url).format().toString()
Toast.makeText(activity, txt, Toast.LENGTH_SHORT).show() Toast.makeText(activity, txt, Toast.LENGTH_SHORT).show()
} }
return@launch }
} }
} }
} }

View File

@ -1,5 +0,0 @@
package org.thoughtcrime.securesms.qr;
public interface ScanListener {
public void onQrDataFound(String data);
}

View File

@ -1,125 +0,0 @@
package org.thoughtcrime.securesms.qr;
import android.content.res.Configuration;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.DecodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import org.thoughtcrime.securesms.components.camera.CameraView;
import org.thoughtcrime.securesms.components.camera.CameraView.PreviewFrame;
import org.session.libsignal.utilities.Log;
import org.session.libsession.utilities.Util;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
public class ScanningThread extends Thread implements CameraView.PreviewCallback {
private static final String TAG = ScanningThread.class.getSimpleName();
private final QRCodeReader reader = new QRCodeReader();
private final AtomicReference<ScanListener> scanListener = new AtomicReference<>();
private final Map<DecodeHintType, String> hints = new HashMap<>();
private boolean scanning = true;
private PreviewFrame previewFrame;
public void setCharacterSet(String characterSet) {
hints.put(DecodeHintType.CHARACTER_SET, characterSet);
}
public void setScanListener(ScanListener scanListener) {
this.scanListener.set(scanListener);
}
@Override
public void onPreviewFrame(@NonNull PreviewFrame previewFrame) {
try {
synchronized (this) {
this.previewFrame = previewFrame;
this.notify();
}
} catch (RuntimeException e) {
Log.w(TAG, e);
}
}
@Override
public void run() {
while (true) {
PreviewFrame ourFrame;
synchronized (this) {
while (scanning && previewFrame == null) {
Util.wait(this, 0);
}
if (!scanning) return;
else ourFrame = previewFrame;
previewFrame = null;
}
String data = getScannedData(ourFrame.getData(), ourFrame.getWidth(), ourFrame.getHeight(), ourFrame.getOrientation());
ScanListener scanListener = this.scanListener.get();
if (data != null && scanListener != null) {
scanListener.onQrDataFound(data);
return;
}
}
}
public void stopScanning() {
synchronized (this) {
scanning = false;
notify();
}
}
private @Nullable String getScannedData(byte[] data, int width, int height, int orientation) {
try {
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
byte[] rotatedData = new byte[data.length];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
rotatedData[x * height + height - y - 1] = data[x + y * width];
}
}
int tmp = width;
width = height;
height = tmp;
data = rotatedData;
}
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, width, height,
0, 0, width, height,
false);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = reader.decode(bitmap, hints);
if (result != null) return result.getText();
} catch (NullPointerException | ChecksumException | FormatException | IndexOutOfBoundsException e) {
Log.w(TAG, e);
} catch (NotFoundException e) {
// Thanks ZXing...
}
return null;
}
}

View File

@ -1,65 +0,0 @@
package org.thoughtcrime.securesms.util
import android.content.res.Configuration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import network.loki.messenger.databinding.FragmentScanQrCodeBinding
import org.thoughtcrime.securesms.qr.ScanListener
import org.thoughtcrime.securesms.qr.ScanningThread
class ScanQRCodeFragment : Fragment() {
private lateinit var binding: FragmentScanQrCodeBinding
private val scanningThread = ScanningThread()
var scanListener: ScanListener? = null
set(value) { field = value; scanningThread.setScanListener(scanListener) }
var message: CharSequence = ""
override fun onCreateView(layoutInflater: LayoutInflater, viewGroup: ViewGroup?, bundle: Bundle?): View {
binding = FragmentScanQrCodeBinding.inflate(layoutInflater, viewGroup, false)
return binding.root
}
override fun onViewCreated(view: View, bundle: Bundle?) {
super.onViewCreated(view, bundle)
when (resources.configuration.orientation) {
Configuration.ORIENTATION_LANDSCAPE -> binding.overlayView.orientation = LinearLayout.HORIZONTAL
else -> binding.overlayView.orientation = LinearLayout.VERTICAL
}
binding.messageTextView.text = message
binding.messageTextView.isVisible = message.isNotEmpty()
}
override fun onResume() {
super.onResume()
binding.cameraView.onResume()
binding.cameraView.setPreviewCallback(scanningThread)
try {
scanningThread.start()
} catch (exception: Exception) {
// Do nothing
}
scanningThread.setScanListener(scanListener)
}
override fun onConfigurationChanged(newConfiguration: Configuration) {
super.onConfigurationChanged(newConfiguration)
binding.cameraView.onPause()
when (newConfiguration.orientation) {
Configuration.ORIENTATION_LANDSCAPE -> binding.overlayView.orientation = LinearLayout.HORIZONTAL
else -> binding.overlayView.orientation = LinearLayout.VERTICAL
}
binding.cameraView.onResume()
binding.cameraView.setPreviewCallback(scanningThread)
}
override fun onPause() {
super.onPause()
this.binding.cameraView.onPause()
this.scanningThread.stopScanning()
}
}

View File

@ -1,34 +0,0 @@
package org.thoughtcrime.securesms.util
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.squareup.phrase.Phrase
import network.loki.messenger.R
import network.loki.messenger.databinding.FragmentScanQrCodePlaceholderBinding
import org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY
class ScanQRCodePlaceholderFragment: Fragment() {
private lateinit var binding: FragmentScanQrCodePlaceholderBinding
var delegate: ScanQRCodePlaceholderFragmentDelegate? = null
override fun onCreateView(layoutInflater: LayoutInflater, viewGroup: ViewGroup?, bundle: Bundle?): View {
binding = FragmentScanQrCodePlaceholderBinding.inflate(layoutInflater, viewGroup, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.grantCameraAccessButton.setOnClickListener { delegate?.requestCameraAccess() }
binding.needCameraPermissionsTV.text = Phrase.from(context, R.string.cameraGrantAccessQr)
.put(APP_NAME_KEY, getString(R.string.app_name))
.format()
}
}
interface ScanQRCodePlaceholderFragmentDelegate {
fun requestCameraAccess()
}

View File

@ -1,89 +1,27 @@
package org.thoughtcrime.securesms.util package org.thoughtcrime.securesms.util
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle 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.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.tbruyelle.rxpermissions2.RxPermissions import kotlinx.coroutines.flow.emptyFlow
import network.loki.messenger.R import org.thoughtcrime.securesms.ui.components.QRScannerScreen
import org.thoughtcrime.securesms.qr.ScanListener import org.thoughtcrime.securesms.ui.createThemedComposeView
class ScanQRCodeWrapperFragment : Fragment(), ScanQRCodePlaceholderFragmentDelegate, ScanListener { class ScanQRCodeWrapperFragment : Fragment() {
companion object { companion object {
const val FRAGMENT_TAG = "ScanQRCodeWrapperFragment_FRAGMENT_TAG" const val FRAGMENT_TAG = "ScanQRCodeWrapperFragment_FRAGMENT_TAG"
} }
var delegate: ScanQRCodeWrapperFragmentDelegate? = null var delegate: ScanQRCodeWrapperFragmentDelegate? = null
var message: CharSequence = ""
var enabled: Boolean = true
set(value) {
val shouldUpdate = field != value // update if value changes (view appears or disappears)
field = value
if (shouldUpdate) {
update()
}
}
@Deprecated("Deprecated in Java") override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
override fun setUserVisibleHint(isVisibleToUser: Boolean) { createThemedComposeView {
super.setUserVisibleHint(isVisibleToUser) QRScannerScreen(emptyFlow(), onScan = {
enabled = isVisibleToUser delegate?.handleQRCodeScanned(it)
} })
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_scan_qr_code_wrapper, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
update()
}
private fun update() {
if (!this.isAdded) return
val fragment: Fragment
if (!enabled) {
val manager = childFragmentManager
manager.findFragmentByTag(FRAGMENT_TAG)?.let { existingFragment ->
// remove existing camera fragment (if switching back to other page)
manager.beginTransaction().remove(existingFragment).commit()
}
return
}
if (ContextCompat.checkSelfPermission(requireActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
val scanQRCodeFragment = ScanQRCodeFragment()
scanQRCodeFragment.scanListener = this
scanQRCodeFragment.message = message
fragment = scanQRCodeFragment
} else {
val scanQRCodePlaceholderFragment = ScanQRCodePlaceholderFragment()
scanQRCodePlaceholderFragment.delegate = this
fragment = scanQRCodePlaceholderFragment
}
val transaction = childFragmentManager.beginTransaction()
transaction.replace(R.id.fragmentContainer, fragment, FRAGMENT_TAG)
transaction.commit()
}
override fun requestCameraAccess() {
@SuppressWarnings("unused")
val unused = RxPermissions(this).request(Manifest.permission.CAMERA).subscribe { isGranted ->
if (isGranted) {
update()
}
}
}
override fun onQrDataFound(data: String) {
activity?.runOnUiThread {
delegate?.handleQRCodeScanned(data)
}
} }
} }

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.thoughtcrime.securesms.components.camera.CameraView
android:id="@+id/cameraView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:camera="0" />
<LinearLayout
android:id="@+id/overlayView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="3" >
<org.thoughtcrime.securesms.components.ShapeScrim
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="0dp"/>
<TextView
android:id="@+id/messageTextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="@dimen/very_large_spacing"
android:gravity="center"
android:text="@string/messageNewDescriptionMobile"
android:background="?android:windowBackground"
android:textSize="@dimen/small_font_size"
android:textColor="?android:textColorTertiary" />
</LinearLayout>
</FrameLayout>

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_centerInParent="true">
<TextView
android:id="@+id/needCameraPermissionsTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/very_large_spacing"
android:layout_marginRight="@dimen/very_large_spacing"
android:textSize="@dimen/small_font_size"
android:textAlignment="center"
android:text="@string/cameraGrantAccessQr" />
<Button
style="@style/Widget.Session.Button.Common.ProminentOutline"
android:id="@+id/grantCameraAccessButton"
android:layout_width="wrap_content"
android:layout_height="@dimen/medium_button_height"
android:layout_marginTop="@dimen/medium_spacing"
android:paddingLeft="@dimen/medium_spacing"
android:paddingRight="@dimen/medium_spacing"
android:text="@string/cameraGrantAccess" />
</LinearLayout>
</RelativeLayout>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />