Skip to content
Closed
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
8 changes: 8 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,14 @@
android:theme="@style/SaveAppTheme.NoActionBar"
android:windowSoftInputMode="adjustPan" />

<activity
android:name=".services.snowbird.SnowbirdActivity"
android:exported="false"
android:label="@string/dweb_title"
android:taskAffinity=""
android:theme="@style/SaveAppTheme.NoActionBar"
android:windowSoftInputMode="adjustPan" />

<activity
android:name=".features.onboarding.Onboarding23Activity"
android:exported="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ val passcodeModule = module {
maxRetryLimitEnabled = false,
biometricAuthEnabled = false,
maxFailedAttempts = 5,
isDwebEnabled = true,
isDwebEnabled = false,
useCustomCamera = true,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package net.opendasharchive.openarchive.features.core
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import net.opendasharchive.openarchive.analytics.api.AnalyticsManager
Expand All @@ -12,11 +11,12 @@ import net.opendasharchive.openarchive.core.logger.AppLogger
import net.opendasharchive.openarchive.features.core.dialog.DialogStateManager
import net.opendasharchive.openarchive.features.onboarding.SpaceSetupActivity
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.activityViewModel
import kotlin.getValue

abstract class BaseFragment : Fragment(), ToolbarConfigurable {

protected val dialogManager: DialogStateManager by activityViewModels()
protected val dialogManager: DialogStateManager by activityViewModel()

// Inject analytics dependencies
protected val analyticsManager: AnalyticsManager by inject()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import android.widget.PopupWindow
import androidx.activity.result.IntentSenderRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
Expand Down Expand Up @@ -70,6 +69,7 @@ import net.opendasharchive.openarchive.features.onboarding.Onboarding23Activity
import net.opendasharchive.openarchive.features.onboarding.SpaceSetupActivity
import net.opendasharchive.openarchive.features.onboarding.StartDestination
import net.opendasharchive.openarchive.features.settings.passcode.AppConfig
import net.opendasharchive.openarchive.services.snowbird.SnowbirdActivity
import net.opendasharchive.openarchive.services.snowbird.SnowbirdBridge
import net.opendasharchive.openarchive.services.snowbird.service.SnowbirdService
import net.opendasharchive.openarchive.upload.UploadManagerFragment
Expand Down Expand Up @@ -1238,8 +1238,7 @@ class MainActivity : BaseActivity(), SpaceDrawerAdapterListener, FolderDrawerAda
override fun onNavigateToDwebGroups() {
collapseSpacesList()
closeDrawer()
val intent = Intent(this, SpaceSetupActivity::class.java)
intent.putExtra("start_destination", StartDestination.DWEB_DASHBOARD.name)
val intent = Intent(this, SnowbirdActivity::class.java)
startActivity(intent)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import net.opendasharchive.openarchive.features.settings.FoldersFragment
enum class StartDestination {
SPACE_TYPE,
SPACE_LIST,
DWEB_DASHBOARD,
ADD_FOLDER,
ADD_NEW_FOLDER,
ARCHIVED_FOLDER_LIST
Expand Down Expand Up @@ -103,9 +102,6 @@ class SpaceSetupActivity : BaseActivity() {
navController.setGraph(navGraph, bundle)
return // Early return to avoid setting graph again
}
StartDestination.DWEB_DASHBOARD -> {
navGraph.setStartDestination(R.id.snowbird_nav_graph)
}
else -> {
navGraph.setStartDestination(R.id.fragment_space_setup)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.content.Intent
import androidx.fragment.compose.content
import androidx.navigation.fragment.findNavController
import net.opendasharchive.openarchive.R
Expand All @@ -13,6 +14,7 @@ import net.opendasharchive.openarchive.features.core.BaseFragment
import net.opendasharchive.openarchive.features.settings.passcode.AppConfig
import net.opendasharchive.openarchive.features.spaces.SpaceSetupScreen
import org.koin.android.ext.android.inject
import net.opendasharchive.openarchive.services.snowbird.SnowbirdActivity

class SpaceSetupFragment : BaseFragment() {

Expand All @@ -39,9 +41,8 @@ class SpaceSetupFragment : BaseFragment() {
// Show/hide Snowbird based on config
val isDwebEnabled = appConfig.isDwebEnabled
val onDwebClicked = {
val action =
SpaceSetupFragmentDirections.actionFragmentSpaceSetupToFragmentSnowbird()
findNavController().navigate(action)
val intent = Intent(requireContext(), SnowbirdActivity::class.java)
startActivity(intent)
}

SaveAppTheme {
Expand All @@ -59,4 +60,4 @@ class SpaceSetupFragment : BaseFragment() {
override fun getToolbarTitle() = getString(R.string.space_setup_title)
override fun getToolbarSubtitle(): String? = null
override fun shouldShowBackButton() = true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,12 @@ package net.opendasharchive.openarchive.features.settings
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.MenuProvider
import androidx.fragment.app.setFragmentResult
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.navigation.navOptions
import net.opendasharchive.openarchive.R
import net.opendasharchive.openarchive.databinding.FragmentSpaceSetupSuccessBinding
import net.opendasharchive.openarchive.db.Space
import net.opendasharchive.openarchive.features.core.BaseFragment
import net.opendasharchive.openarchive.features.main.MainActivity
import net.opendasharchive.openarchive.util.extensions.applyEdgeToEdgeInsets
Expand Down Expand Up @@ -50,62 +41,15 @@ class SpaceSetupSuccessFragment : BaseFragment() {
}

binding.btAuthenticate.setOnClickListener { _ ->
if (args.spaceType == Space.Type.RAVEN) {
val navController = findNavController()
// Navigate to Snowbird as the new root of this nav graph so Back exits to MainActivity
navController.navigate(
R.id.action_fragment_space_setup_success_to_fragment_snowbird,
null,
navOptions {
// Clear the entire Space Setup nav graph back stack
popUpTo(R.id.space_setup_navigation) { inclusive = true }
launchSingleTop = true
restoreState = false
}
)
} else {
val intent = Intent(requireActivity(), MainActivity::class.java)
intent.flags =
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK // Clears backstack
startActivity(intent)
}
}

return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

if (args.spaceType == Space.Type.RAVEN) {
// Add the menu provider
requireActivity().addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.menu_space_setup_success, menu)
}

override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
R.id.action_share_group -> {
if (args.dwebGroupKey != null) {
val action =
SpaceSetupSuccessFragmentDirections.actionFragmentSpaceSetupSuccessToFragmentSnowbirdShareGroup(
dwebGroupKey = args.dwebGroupKey!!,
isSetupOngoing = true
)

findNavController().navigate(action)
}
true
}

else -> false
}
}
}, viewLifecycleOwner)
}
}

override fun getToolbarTitle() = getString(R.string.space_setup_success_title)
override fun shouldShowBackButton() = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ data class AppConfig(
val maxRetryLimitEnabled: Boolean = false,
val biometricAuthEnabled: Boolean = false,
val maxFailedAttempts: Int = 5,
val isDwebEnabled: Boolean = true,
val isDwebEnabled: Boolean = false,
val multipleProjectSelectionMode: Boolean = false,
val useCustomCamera: Boolean = false,
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,98 @@
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import net.opendasharchive.openarchive.R
import net.opendasharchive.openarchive.analytics.api.AnalyticsManager
import net.opendasharchive.openarchive.analytics.api.session.SessionTracker
import net.opendasharchive.openarchive.core.logger.AppLogger
import net.opendasharchive.openarchive.db.SnowbirdError
import net.opendasharchive.openarchive.extensions.androidViewModel
import net.opendasharchive.openarchive.features.core.BaseActivity
import net.opendasharchive.openarchive.features.core.BaseFragment
import net.opendasharchive.openarchive.features.core.ToolbarConfigurable
import net.opendasharchive.openarchive.features.core.UiText
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 org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.activityViewModel

abstract class BaseSnowbirdFragment : BaseFragment() {
abstract class BaseSnowbirdFragment : Fragment(), ToolbarConfigurable {

protected val dialogManager: DialogStateManager by activityViewModel()
protected val analyticsManager: AnalyticsManager by inject()
protected val sessionTracker: SessionTracker by inject()

private var screenStartTime: Long = 0
private var previousScreen: String = ""

val snowbirdGroupViewModel: SnowbirdGroupViewModel by androidViewModel()
val snowbirdRepoViewModel: SnowbirdRepoViewModel by androidViewModel()

protected open fun getScreenName(): String = this::class.simpleName ?: "UnknownSnowbirdFragment"

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
ensureComposeDialogHost()
}

private fun ensureComposeDialogHost() {
(requireActivity() as? BaseActivity)?.ensureComposeDialogHost()
}

open fun dismissKeyboard(view: View) {
val imm = view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.windowToken, 0)
}

open fun handleError(error: SnowbirdError) {
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) {
if (isLoading) {
FullScreenOverlayManager.show(this@BaseSnowbirdFragment)
} else {
FullScreenOverlayManager.hide()
}
}

override fun onResume() {
super.onResume()
(activity as? SpaceSetupActivity)?.updateToolbarFromFragment(this)
(activity as? SnowbirdActivity)?.updateToolbarFromFragment(this)

screenStartTime = System.currentTimeMillis()
val screenName = getScreenName()
AppLogger.setCurrentScreen(screenName)

lifecycleScope.launch {
analyticsManager.trackScreenView(screenName, null, previousScreen)
}
sessionTracker.setCurrentScreen(screenName)

if (previousScreen.isNotEmpty() && previousScreen != screenName) {
lifecycleScope.launch {
analyticsManager.trackNavigation(previousScreen, screenName)
}
}
}

override fun onPause() {
super.onPause()
val timeSpent = (System.currentTimeMillis() - screenStartTime) / 1000

Check warning

Code scanning / detekt

Report magic numbers. Magic number is a numeric literal that is not defined as a constant and hence it's unclear what the purpose of this number is. It's better to declare such numbers as constants and give them a proper name. By default, -1, 0, 1, and 2 are not considered to be magic numbers. Warning

This expression contains a magic number. Consider defining it to a well named constant.
val screenName = getScreenName()

lifecycleScope.launch {
analyticsManager.trackScreenView(screenName, timeSpent, previousScreen)
}

previousScreen = screenName
}
}
}

Check warning

Code scanning / detekt

Library classes should not be public. Warning

Class BaseSnowbirdFragment should not be public
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package net.opendasharchive.openarchive.services.snowbird

import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.NavGraph
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import net.opendasharchive.openarchive.R
import net.opendasharchive.openarchive.databinding.ActivitySnowbirdBinding
import net.opendasharchive.openarchive.features.core.BaseActivity
import net.opendasharchive.openarchive.features.core.ToolbarConfigurable


class SnowbirdActivity : BaseActivity() {

Check warning

Code scanning / detekt

Reports consecutive blank lines Warning

Needless blank line(s)

private lateinit var binding: ActivitySnowbirdBinding
private lateinit var navController: NavController
private lateinit var navGraph: NavGraph
private lateinit var appBarConfiguration: AppBarConfiguration


override fun onCreate(savedInstanceState: Bundle?) {

Check warning

Code scanning / detekt

Reports consecutive blank lines Warning

Needless blank line(s)
super.onCreate(savedInstanceState)

binding = ActivitySnowbirdBinding.inflate(layoutInflater)
setContentView(binding.root)

setupToolbar(showBackButton = true)
initSnowbirdNavigation()
}

private fun initSnowbirdNavigation() {
val navHostFragment = supportFragmentManager.findFragmentById(R.id.snowbird_nav_host_fragment) as NavHostFragment

Check warning

Code scanning / detekt

Reports lines with exceeded length Warning

Exceeded max line length (120)

Check warning

Code scanning / detekt

Reports incorrect argument list wrapping Warning

Argument should be on a separate line (unless all arguments can fit a single line)

Check warning

Code scanning / detekt

Reports incorrect argument list wrapping Warning

Missing newline before ")"

navController = navHostFragment.navController
navGraph = navController.navInflater.inflate(R.navigation.snowbird_nav_graph)

appBarConfiguration = AppBarConfiguration(emptySet())
setupActionBarWithNavController(navController, appBarConfiguration)
}

fun updateToolbarFromFragment(fragment: Fragment) {
if (fragment is ToolbarConfigurable) {
val title = fragment.getToolbarTitle()
val subtitle = fragment.getToolbarSubtitle()
val showBackButton = fragment.shouldShowBackButton()
setupToolbar(title = title, showBackButton = showBackButton)
supportActionBar?.subtitle = subtitle
} else {
setupToolbar(title = getString(R.string.dweb_title), showBackButton = true)
supportActionBar?.subtitle = null
}
}

override fun onSupportNavigateUp(): Boolean {
return if (::navController.isInitialized && navController.currentDestination?.id == R.id.snowbird_dashboard) {
finish()
true
} else {
navController.navigateUp() || super.onSupportNavigateUp()
}
}
}

Check warning

Code scanning / detekt

Library classes should not be public. Warning

Class SnowbirdActivity should not be public
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import net.opendasharchive.openarchive.databinding.FragmentSnowbirdCreateGroupBi
import net.opendasharchive.openarchive.db.SnowbirdError
import net.opendasharchive.openarchive.db.SnowbirdGroup
import net.opendasharchive.openarchive.db.SnowbirdRepo
import net.opendasharchive.openarchive.db.Space
import net.opendasharchive.openarchive.features.core.BaseFragment
import net.opendasharchive.openarchive.util.FullScreenOverlayCreateGroupManager
import net.opendasharchive.openarchive.util.extensions.applyEdgeToEdgeInsets
import java.io.File
Expand Down Expand Up @@ -158,9 +156,8 @@ class SnowbirdCreateGroupFragment : BaseSnowbirdFragment() {
}

val action = SnowbirdCreateGroupFragmentDirections
.actionFragmentSnowbirdCreateGroupToFragmentSpaceSetupSuccess(
.actionFragmentSnowbirdCreateGroupToFragmentSnowbirdSetupSuccess(
message = getString(R.string.you_have_successfully_created_dweb),
spaceType = Space.Type.RAVEN,
dwebGroupKey = group.key,
)
findNavController().navigate(action)
Expand Down
Loading