diff --git a/app/src/main/java/com/h/pixeldroid/MainActivity.kt b/app/src/main/java/com/h/pixeldroid/MainActivity.kt index 9df488de..01c05d2d 100644 --- a/app/src/main/java/com/h/pixeldroid/MainActivity.kt +++ b/app/src/main/java/com/h/pixeldroid/MainActivity.kt @@ -67,17 +67,21 @@ class MainActivity : BaseActivity() { } else { setupDrawer() - val tabs: List = listOf( - PostFeedFragment() - .apply { - arguments = Bundle().apply { putBoolean("home", true) } + val tabs: List<() -> Fragment> = listOf( + { + PostFeedFragment() + .apply { + arguments = Bundle().apply { putBoolean("home", true) } + } }, - SearchDiscoverFragment(), - CameraFragment(), - NotificationsFragment(), - PostFeedFragment() - .apply { - arguments = Bundle().apply { putBoolean("home", false) } + { SearchDiscoverFragment() }, + { CameraFragment() }, + { NotificationsFragment() }, + { + PostFeedFragment() + .apply { + arguments = Bundle().apply { putBoolean("home", false) } + } } ) setupTabs(tabs) @@ -234,13 +238,13 @@ class MainActivity : BaseActivity() { private fun fillDrawerAccountInfo(account: String) { val users = db.userDao().getAll().toMutableList() - users.sortWith(Comparator { l, r -> + users.sortWith { l, r -> when { l.isActive && !r.isActive -> -1 r.isActive && !l.isActive -> 1 else -> 0 } - }) + } val profiles: MutableList = users.map { user -> ProfileDrawerItem().apply { isSelected = user.isActive @@ -264,10 +268,10 @@ class MainActivity : BaseActivity() { } - private fun setupTabs(tab_array: List){ + private fun setupTabs(tab_array: List<() -> Fragment>){ view_pager.adapter = object : FragmentStateAdapter(this) { override fun createFragment(position: Int): Fragment { - return tab_array[position] + return tab_array[position]() } override fun getItemCount(): Int { @@ -275,9 +279,6 @@ class MainActivity : BaseActivity() { } } - //Keep the tabs active to prevent reloads and stutters - view_pager.offscreenPageLimit = tab_array.size - 1 - TabLayoutMediator(tabs, view_pager) { tab, position -> tab.icon = ContextCompat.getDrawable(applicationContext, when(position){ diff --git a/app/src/main/java/com/h/pixeldroid/db/Converters.kt b/app/src/main/java/com/h/pixeldroid/db/Converters.kt index 7e8ca43c..c4c1cf5c 100644 --- a/app/src/main/java/com/h/pixeldroid/db/Converters.kt +++ b/app/src/main/java/com/h/pixeldroid/db/Converters.kt @@ -7,120 +7,122 @@ import com.h.pixeldroid.objects.* import java.util.* class Converters { + private val gson = Gson() + @TypeConverter - fun listToJson(list: List): String = Gson().toJson(list) + fun listToJson(list: List): String = gson.toJson(list) @TypeConverter fun jsonToList(json: String): List = - Gson().fromJson(json, Array::class.java).toList() + gson.fromJson(json, Array::class.java).toList() @TypeConverter - fun dateToJson(date: Date): String = Gson().toJson(date) + fun dateToJson(date: Date): String = gson.toJson(date) @TypeConverter - fun jsonToDate(json: String): Date = Gson().fromJson(json, Date::class.java) + fun jsonToDate(json: String): Date = gson.fromJson(json, Date::class.java) @TypeConverter - fun accountToJson(account: Account): String = Gson().toJson(account) + fun accountToJson(account: Account): String = gson.toJson(account) @TypeConverter - fun jsonToAccount(json: String): Account = Gson().fromJson(json, Account::class.java) + fun jsonToAccount(json: String): Account = gson.fromJson(json, Account::class.java) @TypeConverter - fun statusToJson(status: Status?): String = Gson().toJson(status) + fun statusToJson(status: Status?): String = gson.toJson(status) @TypeConverter - fun jsonToStatus(json: String): Status? = Gson().fromJson(json, Status::class.java) + fun jsonToStatus(json: String): Status? = gson.fromJson(json, Status::class.java) @TypeConverter - fun notificationTypeToJson(type: Notification.NotificationType?): String = Gson().toJson(type) + fun notificationTypeToJson(type: Notification.NotificationType?): String = gson.toJson(type) @TypeConverter - fun jsonToNotificationType(json: String): Notification.NotificationType? = Gson().fromJson( + fun jsonToNotificationType(json: String): Notification.NotificationType? = gson.fromJson( json, Notification.NotificationType::class.java ) @TypeConverter - fun applicationToJson(type: Application?): String = Gson().toJson(type) + fun applicationToJson(type: Application?): String = gson.toJson(type) @TypeConverter - fun jsonToApplication(json: String): Application? = Gson().fromJson( + fun jsonToApplication(json: String): Application? = gson.fromJson( json, Application::class.java ) @TypeConverter - fun cardToJson(type: Card?): String = Gson().toJson(type) + fun cardToJson(type: Card?): String = gson.toJson(type) @TypeConverter - fun jsonToCard(json: String): Card? = Gson().fromJson(json, Card::class.java) + fun jsonToCard(json: String): Card? = gson.fromJson(json, Card::class.java) @TypeConverter - fun attachmentToJson(type: Attachment?): String = Gson().toJson(type) + fun attachmentToJson(type: Attachment?): String = gson.toJson(type) @TypeConverter - fun jsonToAttachment(json: String): Attachment? = Gson().fromJson(json, Attachment::class.java) + fun jsonToAttachment(json: String): Attachment? = gson.fromJson(json, Attachment::class.java) @TypeConverter fun attachmentListToJson(type: List?): String { val listType = object : TypeToken?>() {}.type - return Gson().toJson(type, listType) + return gson.toJson(type, listType) } @TypeConverter fun jsonToAttachmentList(json: String): List? { val listType = object : TypeToken?>() {}.type - return Gson().fromJson(json, listType) + return gson.fromJson(json, listType) } @TypeConverter fun mentionListToJson(type: List?): String { val listType = object : TypeToken?>() {}.type - return Gson().toJson(type, listType) + return gson.toJson(type, listType) } @TypeConverter fun jsonToMentionList(json: String): List? { val listType = object : TypeToken?>() {}.type - return Gson().fromJson(json, listType) + return gson.fromJson(json, listType) } @TypeConverter fun emojiListToJson(type: List?): String { val listType = object : TypeToken?>() {}.type - return Gson().toJson(type, listType) + return gson.toJson(type, listType) } @TypeConverter fun jsonToEmojiList(json: String): List? { val listType = object : TypeToken?>() {}.type - return Gson().fromJson(json, listType) + return gson.fromJson(json, listType) } @TypeConverter fun tagListToJson(type: List?): String { val listType = object : TypeToken?>() {}.type - return Gson().toJson(type, listType) + return gson.toJson(type, listType) } @TypeConverter fun jsonToTagList(json: String): List? { val listType = object : TypeToken?>() {}.type - return Gson().fromJson(json, listType) + return gson.fromJson(json, listType) } @TypeConverter - fun pollToJson(type: Poll?): String = Gson().toJson(type) + fun pollToJson(type: Poll?): String = gson.toJson(type) @TypeConverter - fun jsonToPoll(json: String): Poll? = Gson().fromJson(json, Poll::class.java) + fun jsonToPoll(json: String): Poll? = gson.fromJson(json, Poll::class.java) @TypeConverter - fun visibilityToJson(type: Status.Visibility?): String = Gson().toJson(type) + fun visibilityToJson(type: Status.Visibility?): String = gson.toJson(type) @TypeConverter - fun jsonToVisibility(json: String): Status.Visibility? = Gson().fromJson( + fun jsonToVisibility(json: String): Status.Visibility? = gson.fromJson( json, Status.Visibility::class.java ) diff --git a/app/src/main/java/com/h/pixeldroid/fragments/CameraFragment.kt b/app/src/main/java/com/h/pixeldroid/fragments/CameraFragment.kt index 77eaadd1..ba4b5eb8 100644 --- a/app/src/main/java/com/h/pixeldroid/fragments/CameraFragment.kt +++ b/app/src/main/java/com/h/pixeldroid/fragments/CameraFragment.kt @@ -188,41 +188,45 @@ class CameraFragment : Fragment() { // CameraProvider val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get() - // Preview - preview = Preview.Builder() - // We request aspect ratio but no resolution - .setTargetAspectRatio(screenAspectRatio) - // Set initial target rotation - .setTargetRotation(rotation) - .build() + if (camera == null || preview == null || imageCapture == null || !cameraProvider.isBound(preview!!) || !cameraProvider.isBound(imageCapture!!)) { - // ImageCapture - imageCapture = ImageCapture.Builder() - .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY) - // We request aspect ratio but no resolution to match preview config, but letting - // CameraX optimize for whatever specific resolution best fits our use cases - .setTargetAspectRatio(screenAspectRatio) - // Set initial target rotation, we will have to call this again if rotation changes - // during the lifecycle of this use case - .setTargetRotation(rotation) - .build() - // Must unbind the use-cases before rebinding them - cameraProvider.unbindAll() + // Preview + preview = Preview.Builder() + // We request aspect ratio but no resolution + .setTargetAspectRatio(screenAspectRatio) + // Set initial target rotation + .setTargetRotation(rotation) + .build() - try { - // A variable number of use-cases can be passed here - - // camera provides access to CameraControl & CameraInfo - camera = cameraProvider.bindToLifecycle( - this, cameraSelector, preview, imageCapture - ) + // ImageCapture + imageCapture = ImageCapture.Builder() + .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY) + // We request aspect ratio but no resolution to match preview config, but letting + // CameraX optimize for whatever specific resolution best fits our use cases + .setTargetAspectRatio(screenAspectRatio) + // Set initial target rotation, we will have to call this again if rotation changes + // during the lifecycle of this use case + .setTargetRotation(rotation) + .build() - // Attach the viewfinder's surface provider to preview use case - preview?.setSurfaceProvider(viewFinder.surfaceProvider) - } catch (exc: Exception) { - Log.e(TAG, "Use case binding failed", exc) + // Must unbind the use-cases before rebinding them + cameraProvider.unbindAll() + + try { + // A variable number of use-cases can be passed here - + // camera provides access to CameraControl & CameraInfo + camera = cameraProvider.bindToLifecycle( + this, cameraSelector, preview, imageCapture + ) + + + // Attach the viewfinder's surface provider to preview use case + preview?.setSurfaceProvider(viewFinder.surfaceProvider) + } catch (exc: Exception) { + Log.e(TAG, "Use case binding failed", exc) + } } - }, ContextCompat.getMainExecutor(requireContext())) } @@ -290,7 +294,7 @@ class CameraFragment : Fragment() { private fun setupUploadImage(controls: View) { // Listener for button used to view the most recent photo - controls.findViewById(R.id.photo_view_button).setOnClickListener { + controls.findViewById(R.id.photo_view_button)?.setOnClickListener { Intent().apply { type = "image/*" action = Intent.ACTION_GET_CONTENT @@ -306,7 +310,7 @@ class CameraFragment : Fragment() { private fun setupFlipCameras(controls: View) { // Listener for button used to switch cameras - controls.findViewById(R.id.camera_switch_button).setOnClickListener { + controls.findViewById(R.id.camera_switch_button)?.setOnClickListener { lensFacing = if (CameraSelector.LENS_FACING_FRONT == lensFacing) { CameraSelector.LENS_FACING_BACK } else { @@ -327,7 +331,7 @@ class CameraFragment : Fragment() { private fun setupImageCapture(controls: View) { // Listener for button used to capture photo - controls.findViewById(R.id.camera_capture_button).setOnClickListener { + controls.findViewById(R.id.camera_capture_button)?.setOnClickListener { // Get a stable reference of the modifiable image capture use case imageCapture?.let { imageCapture ->