Compare commits
1 Commits
dev_backen
...
composeTes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16eecf6c08 |
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
|
|||||||
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
@@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||||
|
|||||||
@@ -72,4 +72,6 @@ dependencies {
|
|||||||
|
|
||||||
implementation("androidx.compose.foundation:foundation:1.6.0") // Use your current Compose version
|
implementation("androidx.compose.foundation:foundation:1.6.0") // Use your current Compose version
|
||||||
implementation("androidx.compose.material3:material3:1.2.1") // <-- Fix/Reconfirm Material 3
|
implementation("androidx.compose.material3:material3:1.2.1") // <-- Fix/Reconfirm Material 3
|
||||||
|
|
||||||
|
implementation("io.coil-kt:coil-compose:2.6.0")
|
||||||
}
|
}
|
||||||
@@ -27,3 +27,4 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.placeholder.sherpai2.data.photos
|
||||||
|
|
||||||
|
data class Photo(
|
||||||
|
val id: String,
|
||||||
|
val uri: String,
|
||||||
|
val title: String? = null,
|
||||||
|
val timestamp: Long
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Album(
|
||||||
|
val id: String,
|
||||||
|
val title: String,
|
||||||
|
val photos: List<Photo>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class AlbumPhoto(
|
||||||
|
val id: Int,
|
||||||
|
val imageUrl: String,
|
||||||
|
val description: String
|
||||||
|
)
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.placeholder.sherpai2.data.photos
|
||||||
|
|
||||||
|
import com.placeholder.sherpai2.data.photos.Photo
|
||||||
|
|
||||||
|
object SamplePhotoSource {
|
||||||
|
|
||||||
|
fun loadPhotos(): List<Photo> {
|
||||||
|
return listOf(
|
||||||
|
Photo(
|
||||||
|
id = "1",
|
||||||
|
uri = "file:///sdcard/Pictures/20200115_181335.jpg",
|
||||||
|
title = "Sample One",
|
||||||
|
timestamp = System.currentTimeMillis()
|
||||||
|
),
|
||||||
|
Photo(
|
||||||
|
id = "2",
|
||||||
|
uri = "file:///sdcard/Pictures/20200115_181417.jpg",
|
||||||
|
title = "Sample Two",
|
||||||
|
timestamp = System.currentTimeMillis()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// /sdcard/Pictures/20200115_181335.jpg
|
||||||
|
// /sdcard/Pictures/20200115_181417.jpg
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.placeholder.sherpai2.data.repo
|
||||||
|
|
||||||
|
import com.placeholder.sherpai2.data.photos.Photo
|
||||||
|
import com.placeholder.sherpai2.data.photos.SamplePhotoSource
|
||||||
|
|
||||||
|
class PhotoRepository {
|
||||||
|
|
||||||
|
fun getPhotos(): List<Photo> {
|
||||||
|
return SamplePhotoSource.loadPhotos()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,11 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
|||||||
*/
|
*/
|
||||||
sealed class AppDestinations(val route: String, val icon: ImageVector, val label: String) {
|
sealed class AppDestinations(val route: String, val icon: ImageVector, val label: String) {
|
||||||
// Core Functional Sections
|
// Core Functional Sections
|
||||||
|
object Tour : AppDestinations(
|
||||||
|
route = "Tour",
|
||||||
|
icon = Icons.Default.PhotoLibrary,
|
||||||
|
label = "Tour"
|
||||||
|
)
|
||||||
object Search : AppDestinations("search", Icons.Default.Search, "Search")
|
object Search : AppDestinations("search", Icons.Default.Search, "Search")
|
||||||
object Models : AppDestinations("models", Icons.Default.Layers, "Models")
|
object Models : AppDestinations("models", Icons.Default.Layers, "Models")
|
||||||
object Inventory : AppDestinations("inv", Icons.Default.Inventory2, "Inv")
|
object Inventory : AppDestinations("inv", Icons.Default.Inventory2, "Inv")
|
||||||
@@ -23,6 +28,7 @@ sealed class AppDestinations(val route: String, val icon: ImageVector, val label
|
|||||||
|
|
||||||
// Lists used by the AppDrawerContent to render the menu sections easily
|
// Lists used by the AppDrawerContent to render the menu sections easily
|
||||||
val mainDrawerItems = listOf(
|
val mainDrawerItems = listOf(
|
||||||
|
AppDestinations.Tour,
|
||||||
AppDestinations.Search,
|
AppDestinations.Search,
|
||||||
AppDestinations.Models,
|
AppDestinations.Models,
|
||||||
AppDestinations.Inventory,
|
AppDestinations.Inventory,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ fun MainScreen() {
|
|||||||
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
// State to track which screen is currently visible
|
// State to track which screen is currently visible
|
||||||
//var currentScreen by remember { mutableStateOf(AppDestinations.Search) }
|
// var currentScreen by remember { mutableStateOf(AppDestinations.Search) }
|
||||||
var currentScreen: AppDestinations by remember { mutableStateOf(AppDestinations.Search) }
|
var currentScreen: AppDestinations by remember { mutableStateOf(AppDestinations.Search) }
|
||||||
|
|
||||||
// ModalNavigationDrawer provides the left sidebar UI/UX
|
// ModalNavigationDrawer provides the left sidebar UI/UX
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
// In presentation/MainContentArea.kt
|
// In presentation/MainContentArea.kt
|
||||||
package com.placeholder.sherpai2.presentation
|
package com.placeholder.sherpai2.presentation
|
||||||
|
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.placeholder.sherpai2.navigation.AppDestinations
|
import com.placeholder.sherpai2.navigation.AppDestinations
|
||||||
|
import com.placeholder.sherpai2.ui.theme.SherpAI2Theme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainContentArea(currentScreen: AppDestinations, modifier: Modifier = Modifier) {
|
fun MainContentArea(currentScreen: AppDestinations, modifier: Modifier = Modifier) {
|
||||||
@@ -21,7 +26,8 @@ fun MainContentArea(currentScreen: AppDestinations, modifier: Modifier = Modifie
|
|||||||
) {
|
) {
|
||||||
// Swaps the UI content based on the selected screen from the drawer
|
// Swaps the UI content based on the selected screen from the drawer
|
||||||
when (currentScreen) {
|
when (currentScreen) {
|
||||||
AppDestinations.Search -> SimplePlaceholder("Search Screen: Find your models and data.")
|
AppDestinations.Tour -> TwinAlbumScreen("New Collections." , "Classics")
|
||||||
|
AppDestinations.Search -> SimplePlaceholder("Search for your photo.")
|
||||||
AppDestinations.Models -> SimplePlaceholder("Models Screen: Manage your LoRA/embeddings.")
|
AppDestinations.Models -> SimplePlaceholder("Models Screen: Manage your LoRA/embeddings.")
|
||||||
AppDestinations.Inventory -> SimplePlaceholder("Inventory Screen: View all collected data.")
|
AppDestinations.Inventory -> SimplePlaceholder("Inventory Screen: View all collected data.")
|
||||||
AppDestinations.Train -> SimplePlaceholder("Train Screen: Start the LoRA adaptation process.")
|
AppDestinations.Train -> SimplePlaceholder("Train Screen: Start the LoRA adaptation process.")
|
||||||
@@ -40,3 +46,59 @@ private fun SimplePlaceholder(text: String) {
|
|||||||
modifier = Modifier.padding(16.dp)
|
modifier = Modifier.padding(16.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AlbumPreview(title: String, color: Color) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(8.dp)
|
||||||
|
.aspectRatio(1f) // Makes it a square
|
||||||
|
.background(color, shape = RoundedCornerShape(12.dp)),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text(text = title, color = Color.White, fontWeight = FontWeight.Bold)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TwinAlbumScreen(albumNameA: String, albumNameB: String) {
|
||||||
|
Column(modifier = Modifier.fillMaxSize()) {
|
||||||
|
// --- Top 40% Section ---
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(0.30f) // This takes exactly 40% of vertical space
|
||||||
|
.padding(16.dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(2.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
// These two occupy the 40% area
|
||||||
|
Box(modifier = Modifier.weight(1f)) {
|
||||||
|
AlbumPreview("Mackenzie Hazer", Color.Blue)
|
||||||
|
}
|
||||||
|
Box(modifier = Modifier.weight(1f)) {
|
||||||
|
AlbumPreview("Winifred", Color.Magenta)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Bottom 60% Section ---
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(0.6f) // This takes the remaining 60%
|
||||||
|
.background(Color.LightGray.copy(alpha = 0.2f))
|
||||||
|
) {
|
||||||
|
Text("Other content goes here", modifier = Modifier.align(Alignment.Center))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun PreviewTwinTopRow() {
|
||||||
|
SherpAI2Theme {
|
||||||
|
TwinAlbumScreen("Album A", "Album B")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.placeholder.sherpai2.presentation
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
import coil.compose.rememberAsyncImagePainter
|
||||||
|
|
||||||
|
import com.placeholder.sherpai2.data.photos.Photo
|
||||||
|
import com.placeholder.sherpai2.data.photos.SamplePhotoSource
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PhotoListScreen(
|
||||||
|
photos: List<Photo>
|
||||||
|
) {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentPadding = PaddingValues(8.dp)
|
||||||
|
) {
|
||||||
|
items(photos, key = { it.id }) { photo ->
|
||||||
|
Image(
|
||||||
|
painter = rememberAsyncImagePainter(photo.uri),
|
||||||
|
contentDescription = photo.title,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(200.dp)
|
||||||
|
.padding(bottom = 8.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
package com.placeholder.sherpai2.ui.tourscreen
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.CardDefaults
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import com.placeholder.sherpai2.data.photos.Album
|
||||||
|
import com.placeholder.sherpai2.ui.theme.SherpAI2Theme
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import coil.compose.AsyncImage
|
||||||
|
import com.placeholder.sherpai2.presentation.AlbumPreview
|
||||||
|
|
||||||
|
class GalleryScreen {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun GalleryContent(topAlbums: List<Album>) {
|
||||||
|
Column(modifier = Modifier.fillMaxSize()) {
|
||||||
|
// --- Top 40% Section ---
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(0.4f)
|
||||||
|
.padding(8.dp)
|
||||||
|
) {
|
||||||
|
// We use .getOrNull to safely check if the albums exist in the list
|
||||||
|
val firstAlbum = topAlbums.getOrNull(0)
|
||||||
|
val secondAlbum = topAlbums.getOrNull(1)
|
||||||
|
|
||||||
|
if (firstAlbum != null) {
|
||||||
|
AlbumPreviewBoxRandom(album = firstAlbum, modifier = Modifier.weight(1f))
|
||||||
|
} else {
|
||||||
|
Box(modifier = Modifier.weight(1f)) // Empty placeholder
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secondAlbum != null) {
|
||||||
|
AlbumPreviewBoxRandom(album = secondAlbum, modifier = Modifier.weight(1f))
|
||||||
|
} else {
|
||||||
|
Box(modifier = Modifier.weight(1f)) // Empty placeholder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Bottom 60% Section ---
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(0.6f)
|
||||||
|
) {
|
||||||
|
Text("Lower Content Area", modifier = Modifier.align(Alignment.Center))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// --- STATEFUL (Use this for Production) ---
|
||||||
|
@Composable
|
||||||
|
fun GalleryScreen(viewModel: GalleryViewModel = viewModel()) {
|
||||||
|
val albumList by viewModel.albums
|
||||||
|
GalleryContent(topAlbums = albumList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- PREVIEW ---
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun GalleryPreview() {
|
||||||
|
SherpAI2Theme {
|
||||||
|
// Feed mock data into the Stateless version
|
||||||
|
GalleryContent(topAlbums = listOf(/* Fake Album Objects */))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AlbumPreviewBox(
|
||||||
|
album: Album,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Card(
|
||||||
|
modifier = modifier
|
||||||
|
.padding(8.dp)
|
||||||
|
.aspectRatio(1f), // Keeps it square
|
||||||
|
shape = RoundedCornerShape(12.dp),
|
||||||
|
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color.DarkGray), // Background until image is loaded
|
||||||
|
contentAlignment = Alignment.BottomStart
|
||||||
|
) {
|
||||||
|
// Title Overlay
|
||||||
|
Text(
|
||||||
|
text = album.title,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.background(Color.Black.copy(alpha = 0.5f))
|
||||||
|
.padding(8.dp),
|
||||||
|
color = Color.White,
|
||||||
|
style = MaterialTheme.typography.labelLarge
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AlbumPreviewBoxRandom(album: Album, modifier: Modifier = Modifier) {
|
||||||
|
Card(
|
||||||
|
modifier = modifier.padding(8.dp).aspectRatio(1f),
|
||||||
|
shape = RoundedCornerShape(12.dp)
|
||||||
|
) {
|
||||||
|
Row(modifier = Modifier.fillMaxSize()) {
|
||||||
|
// Loop through the 3 random photos in the album
|
||||||
|
album.photos.forEach { photo ->
|
||||||
|
AsyncImage(
|
||||||
|
model = photo.uri,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.fillMaxHeight(),
|
||||||
|
contentScale = ContentScale.Crop // Fills the space nicely
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package com.placeholder.sherpai2.ui.tourscreen
|
||||||
|
|
||||||
|
import android.os.Environment
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.placeholder.sherpai2.data.photos.AlbumPhoto
|
||||||
|
import androidx.compose.runtime.State
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.placeholder.sherpai2.data.photos.Album // Import your data model
|
||||||
|
import com.placeholder.sherpai2.data.photos.Photo
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class GalleryViewModel : ViewModel() {
|
||||||
|
// This is the 'albums' reference your UI is looking for
|
||||||
|
private val _albums = mutableStateOf<List<Album>>(emptyList())
|
||||||
|
val albums: State<List<Album>> = _albums
|
||||||
|
|
||||||
|
init {
|
||||||
|
fetchInitialData()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchInitialData() {
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
val directory = File("/sdcard/photos") // Or: Environment.getExternalStorageDirectory()
|
||||||
|
|
||||||
|
if (directory.exists() && directory.isDirectory) {
|
||||||
|
val photoFiles = directory.listFiles { file ->
|
||||||
|
file.extension.lowercase() in listOf("jpg", "jpeg", "png")
|
||||||
|
} ?: emptyArray()
|
||||||
|
|
||||||
|
// Map files to your Photo data class
|
||||||
|
val loadedPhotos = photoFiles.map { file ->
|
||||||
|
Photo(
|
||||||
|
id = file.absolutePath,
|
||||||
|
uri = file.toURI().toString(),
|
||||||
|
title = file.nameWithoutExtension,
|
||||||
|
timestamp = file.lastModified()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an Album object with these photos
|
||||||
|
val mainAlbum = Album(
|
||||||
|
id = "local_photos",
|
||||||
|
title = "Phone Gallery",
|
||||||
|
photos = loadedPhotos
|
||||||
|
)
|
||||||
|
|
||||||
|
// Update the UI State on the Main Thread
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
_albums.value = listOf(mainAlbum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchInitialDataRandom() {
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
val root = Environment.getExternalStorageDirectory()
|
||||||
|
val directory = File(root, "photos")
|
||||||
|
|
||||||
|
if (directory.exists() && directory.isDirectory) {
|
||||||
|
// 1. Filter specifically for .jpg files
|
||||||
|
val photoFiles = directory.listFiles { file ->
|
||||||
|
file.extension.lowercase() == "jpg"
|
||||||
|
} ?: emptyArray()
|
||||||
|
|
||||||
|
// 2. Shuffle the list and take only the first 3
|
||||||
|
val randomPhotos = photoFiles.asSequence()
|
||||||
|
.shuffled()
|
||||||
|
.take(3)
|
||||||
|
.map { file ->
|
||||||
|
Photo(
|
||||||
|
id = file.absolutePath,
|
||||||
|
uri = file.toURI().toString(),
|
||||||
|
title = file.nameWithoutExtension,
|
||||||
|
timestamp = file.lastModified()
|
||||||
|
)
|
||||||
|
}.toList()
|
||||||
|
|
||||||
|
// 3. Update the state with these 3 random photos
|
||||||
|
val mainAlbum = Album(
|
||||||
|
id = "random_selection",
|
||||||
|
title = "Random Picks",
|
||||||
|
photos = randomPhotos
|
||||||
|
)
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
_albums.value = listOf(mainAlbum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.placeholder.sherpai2.ui.tourscreen.components
|
||||||
|
|
||||||
|
class AlbumBox {
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user