Skip to content

Commit dbdee7b

Browse files
Merge branch 'stage' into ADFA-2883-git-pull-push
2 parents 8b529b5 + ec0a78f commit dbdee7b

12 files changed

Lines changed: 190 additions & 80 deletions

File tree

app/src/main/java/com/itsaky/androidide/activities/MainActivity.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ class MainActivity : EdgeToEdgeIDEActivity() {
400400
builder.show()
401401
}
402402

403-
internal fun openProject(root: File, project: RecentProject? = null) {
403+
internal fun openProject(root: File, project: RecentProject? = null, hasTemplateIssues: Boolean = false) {
404404
ProjectManagerImpl.getInstance().projectPath = root.absolutePath
405405
GeneralPreferences.lastOpenedProject = root.absolutePath
406406

@@ -416,7 +416,7 @@ class MainActivity : EdgeToEdgeIDEActivity() {
416416
}
417417

418418
// Track project open in Firebase Analytics
419-
analyticsManager.trackProjectOpened(root.absolutePath)
419+
analyticsManager.trackProjectOpened(root.absolutePath)
420420

421421
if (isFinishing) {
422422
return
@@ -425,6 +425,9 @@ class MainActivity : EdgeToEdgeIDEActivity() {
425425
val intent =
426426
Intent(this, EditorActivityKt::class.java).apply {
427427
putExtra("PROJECT_PATH", root.absolutePath)
428+
if (hasTemplateIssues) {
429+
putExtra("HAS_TEMPLATE_ISSUES", true)
430+
}
428431
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
429432
}
430433

app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ abstract class BaseEditorActivity :
178178
private val fileManagerViewModel by viewModels<FileManagerViewModel>()
179179
private var feedbackButtonManager: FeedbackButtonManager? = null
180180
private var immersiveController: LandscapeImmersiveController? = null
181+
private val topEdgeThreshold by lazy { SizeUtils.dp2px(TOP_EDGE_SWIPE_THRESHOLD_DP) }
181182

182183
var isDestroying = false
183184
protected set
@@ -398,6 +399,7 @@ abstract class BaseEditorActivity :
398399
protected val log: Logger = LoggerFactory.getLogger(BaseEditorActivity::class.java)
399400

400401
private const val OPTIONS_MENU_INVALIDATION_DELAY = 150L
402+
private const val TOP_EDGE_SWIPE_THRESHOLD_DP = 60f
401403

402404
const val EDITOR_CONTAINER_SCALE_FACTOR = 0.87f
403405
const val KEY_BOTTOM_SHEET_SHOWN = "editor_bottomSheetShown"
@@ -1436,16 +1438,39 @@ abstract class BaseEditorActivity :
14361438
velocityX: Float,
14371439
velocityY: Float,
14381440
): Boolean {
1441+
if (e1 == null) return false
1442+
1443+
val diffX = e2.x - e1.x
1444+
val diffY = e2.y - e1.y
1445+
1446+
val isVerticalSwipe = abs(diffY) > abs(diffX)
1447+
val isHorizontalSwipe = abs(diffX) > abs(diffY)
1448+
1449+
val hasDownFlingDistance = diffY > flingDistanceThreshold
1450+
val hasRightFlingDistance = diffX > flingDistanceThreshold
1451+
1452+
val hasVerticalVelocity = abs(velocityY) > flingVelocityThreshold
1453+
val hasHorizontalVelocity = abs(velocityX) > flingVelocityThreshold
1454+
1455+
// Check for a swipe down (to show top bar)
1456+
// This is placed before the noFilesOpen check so it works while editing
1457+
val isLandscape = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
1458+
val startedNearTopEdge = e1.y < topEdgeThreshold
1459+
1460+
if (isLandscape && startedNearTopEdge && hasDownFlingDistance && hasVerticalVelocity && isVerticalSwipe) {
1461+
immersiveController?.showTopBar()
1462+
return true
1463+
}
1464+
14391465
// Check if no files are open by looking at the displayedChild of the view flipper
14401466
val noFilesOpen = content.viewContainer.displayedChild == 1
14411467
if (!noFilesOpen) {
14421468
return false // If files are open, do nothing
14431469
}
14441470

1445-
val diffX = e2.x - (e1?.x ?: 0f)
1446-
14471471
// Check for a right swipe (to open left drawer) - This part is still correct
1448-
if (diffX > flingDistanceThreshold && abs(velocityX) > flingVelocityThreshold) {
1472+
// Added abs(diffX) > abs(diffY) to prevent diagonal swipes from triggering this
1473+
if (hasRightFlingDistance && hasHorizontalVelocity && isHorizontalSwipe) {
14491474
// Use the correct binding for the drawer layout
14501475
binding.editorDrawerLayout.openDrawer(GravityCompat.START)
14511476
return true

app/src/main/java/com/itsaky/androidide/activities/editor/LandscapeImmersiveController.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ class LandscapeImmersiveController(
230230
bottomToggle.isVisible = visible
231231
}
232232

233-
private fun showTopBar(animate: Boolean = true) {
233+
fun showTopBar(animate: Boolean = true) {
234234
isTopBarRequestedVisible = true
235235
topBar.setExpanded(true, animate)
236236
}

app/src/main/java/com/itsaky/androidide/activities/editor/ProjectHandlerActivity.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ abstract class ProjectHandlerActivity : BaseEditorActivity() {
214214

215215
observeStates()
216216
startServices()
217+
218+
if (intent.getBooleanExtra("HAS_TEMPLATE_ISSUES", false)) {
219+
flashError(getString(string.msg_template_warnings))
220+
}
221+
217222
}
218223

219224
private fun observeStates() {

app/src/main/java/com/itsaky/androidide/fragments/TemplateDetailsFragment.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ class TemplateDetailsFragment :
138138
// open the project
139139
(requireActivity() as MainActivity).openProject(
140140
result.data.projectDir,
141-
project = project
141+
project = project,
142+
hasTemplateIssues = result.hasErrorsWarnings
142143
)
143144
}
144145
}

app/src/main/java/com/itsaky/androidide/fragments/TemplateListFragment.kt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import com.itsaky.androidide.idetooltips.TooltipManager
2929
import com.itsaky.androidide.idetooltips.TooltipTag.EXIT_TO_MAIN
3030
import com.itsaky.androidide.templates.ITemplateProvider
3131
import com.itsaky.androidide.templates.ProjectTemplate
32+
import com.itsaky.androidide.templates.impl.TemplateProviderImpl
33+
import com.itsaky.androidide.utils.flashError
3234
import com.itsaky.androidide.viewmodel.MainViewModel
3335
import org.slf4j.LoggerFactory
3436

@@ -115,11 +117,9 @@ class TemplateListFragment :
115117

116118
log.debug("Reloading templates...")
117119

118-
val templates =
119-
ITemplateProvider
120-
.getInstance(reload = true)
121-
.getTemplates()
122-
.filterIsInstance<ProjectTemplate>()
120+
val provider = ITemplateProvider.getInstance(reload = true)
121+
val templates = provider.getTemplates().filterIsInstance<ProjectTemplate>()
122+
val warnings = (provider as? TemplateProviderImpl)?.warnings.orEmpty()
123123

124124
adapter =
125125
TemplateListAdapter(
@@ -140,5 +140,9 @@ class TemplateListFragment :
140140
)
141141
binding.list.adapter = adapter
142142
updateSpanCount()
143-
}
143+
144+
if (warnings.isNotEmpty()) {
145+
requireActivity().flashError(warnings.joinToString("\n"))
146+
}
147+
}
144148
}

resources/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,8 @@
10161016
<string name="checkbox_delete_source_after_install">Delete installation file after install</string>
10171017
<string name="init_failed_with_reason">%1$s: %2$s</string>
10181018

1019+
<string name="msg_template_warnings">\n\nProject creation finished with warnings/errors. Open IDE Logs for details.</string>
1020+
10191021
<!-- Name of the notification channel which is used to show notifications for wireless debugging -->
10201022
<string name="notification_channel_adb_pairing">Wireless debugging pairing</string>
10211023

templates-api/src/main/java/com/itsaky/androidide/templates/template.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ val data: D
5858
/**
5959
* Result of recipe execution for a [ProjectTemplate].
6060
*/
61-
interface ProjectTemplateRecipeResult : TemplateRecipeResultWithData<ProjectTemplateData>
61+
interface ProjectTemplateRecipeResult : TemplateRecipeResultWithData<ProjectTemplateData> {
62+
val hasErrorsWarnings: Boolean
63+
get() = false
64+
}
6265

6366
/**
6467
* Result of recipe execution for a [ModuleTemplate].

templates-impl/src/main/java/com/itsaky/androidide/templates/impl/TemplateProviderImpl.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class TemplateProviderImpl : ITemplateProvider {
4444
}
4545

4646
private val templates = mutableMapOf<String, Template<*>>()
47+
val warnings: MutableList<String> = mutableListOf()
4748

4849
init {
4950
reload()
@@ -55,14 +56,15 @@ class TemplateProviderImpl : ITemplateProvider {
5556

5657
for (zipFile in list) {
5758
try {
58-
val zipTemplates = ZipTemplateReader.read(zipFile) { json, params, path, data, defModule ->
59+
val zipTemplates = ZipTemplateReader.read(zipFile, warnings) { json, params, path, data, defModule ->
5960
ZipRecipeExecutor({ ZipFile(zipFile) }, json, params, path, data, defModule)
6061
}
6162

6263
for (t in zipTemplates) {
6364
templates[t.templateId] = t
6465
}
6566
} catch (e: Exception) {
67+
warnings.add("Failed to load template archive $zipFile error: ${e.message}")
6668
log.error("Failed to load template from archive: $zipFile", e)
6769
}
6870
}
@@ -78,6 +80,7 @@ class TemplateProviderImpl : ITemplateProvider {
7880

7981
override fun reload() {
8082
release()
83+
warnings.clear()
8184
initializeTemplates()
8285
}
8386

templates-impl/src/main/java/com/itsaky/androidide/templates/impl/base/results.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,18 @@ import com.itsaky.androidide.templates.base.ModuleTemplateBuilder
2525
import com.itsaky.androidide.templates.base.ProjectTemplateBuilder
2626

2727
data class ProjectTemplateRecipeResultImpl(
28-
override val data: ProjectTemplateData
28+
override val data: ProjectTemplateData,
29+
override val hasErrorsWarnings: Boolean = false
2930
) : ProjectTemplateRecipeResult
3031

3132
data class ModuleTemplateRecipeResultImpl(override val data: ModuleTemplateData
3233
) : ModuleTemplateRecipeResult
3334

3435

3536
internal fun ProjectTemplateBuilder.recipeResult(): ProjectTemplateRecipeResult {
36-
return ProjectTemplateRecipeResultImpl(data)
37+
return ProjectTemplateRecipeResultImpl(data)
3738
}
3839

3940
internal fun ModuleTemplateBuilder.recipeResult(): ModuleTemplateRecipeResult {
40-
return ModuleTemplateRecipeResultImpl(data)
41+
return ModuleTemplateRecipeResultImpl(data)
4142
}

0 commit comments

Comments
 (0)