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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@ fastlane/.env
/app/release/baselineProfiles/1/save-unspecified-release.dm
/app/release/output-metadata.json
/app/src/main/assets/.env
/.kotlin/sessions/kotlin-compiler-1215430679833621634.salive
/.kotlin/
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ dependencies {
detektPlugins(libs.detekt.rules.authors)
detektPlugins(libs.detekt.rules.libraries)
detektPlugins(libs.detekt.compose)
detektPlugins(libs.detekt.rules.compose)
}

configurations.all {
Expand Down
1 change: 0 additions & 1 deletion app/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@
<ID>FinalNewline:BaseComposeActivity.kt$net.opendasharchive.openarchive.features.core.BaseComposeActivity.kt</ID>
<ID>FinalNewline:BaseDialog.kt$net.opendasharchive.openarchive.features.core.dialog.BaseDialog.kt</ID>
<ID>FinalNewline:BaseFragment.kt$net.opendasharchive.openarchive.features.core.BaseFragment.kt</ID>
<ID>FinalNewline:BaseSnowbirdFragment.kt$net.opendasharchive.openarchive.services.snowbird.BaseSnowbirdFragment.kt</ID>
<ID>FinalNewline:BaseViewModel.kt$net.opendasharchive.openarchive.util.BaseViewModel.kt</ID>
<ID>FinalNewline:BasicAuthInterceptor.kt$net.opendasharchive.openarchive.services.webdav.BasicAuthInterceptor.kt</ID>
<ID>FinalNewline:BiometricAuthenticator.kt$net.opendasharchive.openarchive.features.settings.passcode.BiometricAuthenticator.kt</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import net.opendasharchive.openarchive.R
import net.opendasharchive.openarchive.db.SnowbirdError
import net.opendasharchive.openarchive.extensions.androidViewModel
import net.opendasharchive.openarchive.features.core.dialog.DialogStateManager
import net.opendasharchive.openarchive.features.core.dialog.showDialog
import net.opendasharchive.openarchive.features.onboarding.SpaceSetupActivity
import net.opendasharchive.openarchive.services.snowbird.SnowbirdGroupViewModel
import net.opendasharchive.openarchive.services.snowbird.SnowbirdRepoViewModel
import net.opendasharchive.openarchive.util.FullScreenOverlayManager
import net.opendasharchive.openarchive.util.Utility

abstract class BaseFragment : Fragment(), ToolbarConfigurable {

Expand Down Expand Up @@ -44,10 +44,13 @@ abstract class BaseFragment : Fragment(), ToolbarConfigurable {
}

open fun handleError(error: SnowbirdError) {
Utility.showMaterialWarning(
requireContext(),
error.friendlyMessage
)
dialogManager.showDialog(dialogManager.requireResourceProvider()) {
title = UiText.DynamicString("Oops")
message = UiText.DynamicString(error.friendlyMessage)
positiveButton {
text = UiText.StringResource(R.string.lbl_ok)
}
}
}

open fun handleLoadingStatus(isLoading: Boolean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.view.Gravity
import android.view.LayoutInflater
import android.view.Menu
Expand All @@ -19,12 +18,8 @@ import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.content.res.AppCompatResources
import androidx.compose.material3.MaterialTheme
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.drawerlayout.widget.DrawerLayout
Expand Down Expand Up @@ -76,12 +71,10 @@ import net.opendasharchive.openarchive.upload.UploadManagerFragment
import net.opendasharchive.openarchive.upload.UploadService
import net.opendasharchive.openarchive.util.Prefs
import net.opendasharchive.openarchive.util.ProofModeHelper
import net.opendasharchive.openarchive.util.Utility
import net.opendasharchive.openarchive.util.extensions.Position
import net.opendasharchive.openarchive.util.extensions.cloak
import net.opendasharchive.openarchive.util.extensions.hide
import net.opendasharchive.openarchive.util.extensions.scaleAndTintDrawable
import net.opendasharchive.openarchive.util.extensions.scaled
import net.opendasharchive.openarchive.util.extensions.show
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel
Expand Down Expand Up @@ -226,10 +219,10 @@ class MainActivity : BaseActivity(), SpaceDrawerAdapterListener, FolderDrawerAda
override fun onStart() {
super.onStart()

if(Prefs.useProofMode){
if (Prefs.useProofMode) {
Prefs.proofModeLocation = true
Prefs.proofModeNetwork = true
}else{
} else {
Prefs.proofModeLocation = false
Prefs.proofModeNetwork = false
}
Expand Down Expand Up @@ -334,9 +327,15 @@ class MainActivity : BaseActivity(), SpaceDrawerAdapterListener, FolderDrawerAda
if (Picker.canPickFiles(this@MainActivity)) {
setAddButtonLongClickEnabled()
onAddLongClick = {
val addMediaBottomSheet =
ContentPickerFragment { actionType -> addClicked(actionType) }
addMediaBottomSheet.show(supportFragmentManager, ContentPickerFragment.TAG)
if (Space.current == null) {
navigateToAddServer()
} else if (getSelectedProject() == null) {
navigateToAddFolder()
} else {
val addMediaBottomSheet =
ContentPickerFragment { actionType -> addClicked(actionType) }
addMediaBottomSheet.show(supportFragmentManager, ContentPickerFragment.TAG)
}
}
supportFragmentManager.setFragmentResultListener(
AddMediaDialogFragment.RESP_TAKE_PHOTO, this@MainActivity
Expand Down Expand Up @@ -763,7 +762,7 @@ class MainActivity : BaseActivity(), SpaceDrawerAdapterListener, FolderDrawerAda
getSelectedProject() != null -> {
if (Prefs.addMediaHint) {
when (mediaType) {
AddMediaType.CAMERA -> Picker.takePhoto(this, mediaLaunchers.cameraLauncher)
AddMediaType.CAMERA -> Picker.takePhoto(this@MainActivity, mediaLaunchers.cameraLauncher)
AddMediaType.GALLERY -> Picker.pickMedia(
this,
mediaLaunchers.imagePickerLauncher
Expand All @@ -778,6 +777,7 @@ class MainActivity : BaseActivity(), SpaceDrawerAdapterListener, FolderDrawerAda
message = R.string.press_and_hold_options_media_screen_message.asUiText(),
onDone = {
Prefs.addMediaHint = true
addClicked(mediaType)
}
)
}
Expand Down Expand Up @@ -831,7 +831,16 @@ class MainActivity : BaseActivity(), SpaceDrawerAdapterListener, FolderDrawerAda
}

private fun showNotificationPermissionRationale() {
Utility.showMaterialWarning(this, "Accept!") { Timber.d("thing") }
dialogManager.showDialog(dialogManager.requireResourceProvider()) {
title = UiText.DynamicString("Notification Permission")
message = UiText.DynamicString("We need permission to post notifications")
positiveButton {
text = UiText.DynamicString("Accept")
action = {
Timber.d("thing")
}
}
}
}

private fun handleIntent(intent: Intent) {
Expand Down Expand Up @@ -879,14 +888,8 @@ class MainActivity : BaseActivity(), SpaceDrawerAdapterListener, FolderDrawerAda
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
2 -> Picker.pickMedia(this, mediaLaunchers.imagePickerLauncher)
REQUEST_CAMERA_PERMISSION -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
takePhoto() // ✅ Permission granted, retry camera
} else {
Toast.makeText(this, "Camera permission denied", Toast.LENGTH_LONG).show()
}
}
REQUEST_FILE_MEDIA -> Picker.pickMedia(this, mediaLaunchers.imagePickerLauncher)
REQUEST_CAMERA_PERMISSION -> Picker.takePhoto(this, mediaLaunchers.cameraLauncher)
}
}

Expand Down Expand Up @@ -971,28 +974,9 @@ class MainActivity : BaseActivity(), SpaceDrawerAdapterListener, FolderDrawerAda
}
}


private fun takePhoto() {
// Check if CAMERA permission is granted
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// Request permission
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQUEST_CAMERA_PERMISSION)
return
}

// If permission is already granted, start the camera intent
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (takePictureIntent.resolveActivity(this.packageManager) != null) {

this.startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
} else {
Toast.makeText(this, "Camera not available", Toast.LENGTH_SHORT).show()
}
}

companion object {
// Define request codes
private const val REQUEST_CAMERA_PERMISSION = 100
private const val REQUEST_IMAGE_CAPTURE = 101
const val REQUEST_CAMERA_PERMISSION = 100
const val REQUEST_FILE_MEDIA = 101
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package net.opendasharchive.openarchive.features.media

import android.content.Intent
import android.net.Uri
import androidx.activity.result.ActivityResultLauncher
import com.esafirm.imagepicker.features.ImagePickerLauncher

data class MediaLaunchers(
val imagePickerLauncher: ImagePickerLauncher,
val filePickerLauncher: ActivityResultLauncher<Intent>,
val cameraLauncher: ActivityResultLauncher<Uri>
val cameraLauncher: ActivityResultLauncher<Intent>
)
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.view.View
import android.widget.ProgressBar
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
Expand All @@ -33,6 +35,8 @@ import net.opendasharchive.openarchive.R
import net.opendasharchive.openarchive.core.logger.AppLogger
import net.opendasharchive.openarchive.db.Media
import net.opendasharchive.openarchive.db.Project
import net.opendasharchive.openarchive.features.main.MainActivity
import net.opendasharchive.openarchive.features.main.MainActivity.Companion.REQUEST_CAMERA_PERMISSION
import net.opendasharchive.openarchive.util.Utility
import net.opendasharchive.openarchive.util.extensions.makeSnackBar
import org.witness.proofmode.crypto.HashUtils
Expand Down Expand Up @@ -81,8 +85,8 @@ object Picker {
}
}

val cpl = activity.registerForActivityResult(ActivityResultContracts.TakePicture()) { success ->
if (success) {
val cpl = activity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == AppCompatActivity.RESULT_OK) {
currentPhotoUri?.let { uri ->

val snackbar = showProgressSnackBar(activity, root, activity.getString(R.string.importing_media))
Expand All @@ -108,9 +112,11 @@ object Picker {

fun pickMedia(activity: Activity, launcher: ImagePickerLauncher) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (needAskForPermission(activity, arrayOf(
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_VIDEO))
if (needAskForPermission(
activity,
arrayOf(Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO),
MainActivity.REQUEST_FILE_MEDIA
)
) {
return
}
Expand Down Expand Up @@ -143,7 +149,7 @@ object Picker {
type = "application/*"
}

private fun needAskForPermission(activity: Activity, permissions: Array<String>): Boolean {
private fun needAskForPermission(activity: Activity, permissions: Array<String>, requestCode: Int): Boolean {
var needAsk = false

for (permission in permissions) {
Expand All @@ -158,7 +164,7 @@ object Picker {

if (!needAsk) return false

ActivityCompat.requestPermissions(activity, permissions, 2)
ActivityCompat.requestPermissions(activity, permissions, requestCode)

return true
}
Expand Down Expand Up @@ -221,16 +227,34 @@ object Picker {
return media
}

fun takePhoto(context: Context, launcher: ActivityResultLauncher<Uri>) {
val file = Utility.getOutputMediaFileByCache(context, "IMG_${System.currentTimeMillis()}.jpg")
fun takePhoto(activity: Activity, launcher: ActivityResultLauncher<Intent>) {

if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// Request permission
ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.CAMERA), REQUEST_CAMERA_PERMISSION)
return
}

val file = Utility.getOutputMediaFileByCache(activity, "IMG_${System.currentTimeMillis()}.jpg")

file?.let {
val uri = FileProvider.getUriForFile(
context, "${context.packageName}.provider",
activity, "${activity.packageName}.provider",
it
)

currentPhotoUri = uri
launcher.launch(uri)

val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
putExtra(MediaStore.EXTRA_OUTPUT, uri)
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) // Ensure permission is granted
}

if (takePictureIntent.resolveActivity(activity.packageManager) != null) {
launcher.launch(takePictureIntent)
} else {
Toast.makeText(activity, "Camera not available", Toast.LENGTH_SHORT).show()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import net.opendasharchive.openarchive.features.core.asUiImage
import net.opendasharchive.openarchive.features.core.asUiText
import net.opendasharchive.openarchive.features.core.dialog.DialogType
import net.opendasharchive.openarchive.features.core.dialog.showDialog
import net.opendasharchive.openarchive.features.main.MainActivity
import net.opendasharchive.openarchive.util.Prefs
import net.opendasharchive.openarchive.util.extensions.hide
import net.opendasharchive.openarchive.util.extensions.show
Expand Down Expand Up @@ -306,4 +307,17 @@ class PreviewActivity : BaseActivity(), View.OnClickListener, PreviewAdapter.Lis

}
}


override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
MainActivity.REQUEST_FILE_MEDIA -> Picker.pickMedia(this, mediaLaunchers.imagePickerLauncher)
MainActivity.REQUEST_CAMERA_PERMISSION -> Picker.takePhoto(this, mediaLaunchers.cameraLauncher)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.MenuItem
import androidx.activity.OnBackPressedCallback
import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent
import net.opendasharchive.openarchive.core.presentation.theme.SaveAppTheme
import net.opendasharchive.openarchive.features.core.BaseActivity
Expand All @@ -17,31 +17,29 @@ class PasscodeSetupActivity : BaseActivity() {
const val EXTRA_PASSCODE_ENABLED = "passcode_enabled"
}

// private val onBackPressedCallback = object : OnBackPressedCallback(enabled = true) {
// override fun handleOnBackPressed() {
// setResult(RESULT_CANCELED)
// finish()
// }
// }


override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

//onBackPressedDispatcher.addCallback(onBackPressedCallback)

setContent {
SaveAppTheme {
DefaultScaffold(
topAppBar = {
ComposeAppBar(
title = "Lock app with passcode",
onNavigationAction = {
//onBackPressedCallback.handleOnBackPressed()
setResult(RESULT_CANCELED)
finish()
}
)
}
) {

// Handle back press inside Compose
BackHandler {
setResult(RESULT_CANCELED)
finish()
}

PasscodeSetupScreen(
onPasscodeSet = {
// Passcode successfully set
Expand Down
Loading
Loading