Skip to content

Commit cd4559a

Browse files
authored
Gallery UI/UX improvements (#233)
* Gallery long click actions scaffold implementation * Gallery context dropdown menu implementation * Finalized gallery UI/UX implementation
1 parent 063baa7 commit cd4559a

File tree

31 files changed

+799
-128
lines changed

31 files changed

+799
-128
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.shifthackz.aisdv1.core.extensions
2+
3+
import androidx.compose.animation.core.LinearEasing
4+
import androidx.compose.animation.core.RepeatMode
5+
import androidx.compose.animation.core.StartOffset
6+
import androidx.compose.animation.core.animateFloat
7+
import androidx.compose.animation.core.infiniteRepeatable
8+
import androidx.compose.animation.core.rememberInfiniteTransition
9+
import androidx.compose.animation.core.tween
10+
import androidx.compose.runtime.getValue
11+
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.composed
13+
import androidx.compose.ui.graphics.graphicsLayer
14+
import androidx.compose.ui.platform.debugInspectorInfo
15+
16+
fun Modifier.shake(
17+
enabled: Boolean,
18+
animationDurationMillis: Int = 167,
19+
animationStartOffset: Int = 0,
20+
) = this.composed(
21+
factory = {
22+
val infiniteTransition = rememberInfiniteTransition(label = "shake")
23+
val scaleInfinite by infiniteTransition.animateFloat(
24+
initialValue = 1f,
25+
targetValue = .99f,
26+
animationSpec = infiniteRepeatable(
27+
animation = tween(animationDurationMillis, easing = LinearEasing),
28+
repeatMode = RepeatMode.Reverse,
29+
initialStartOffset = StartOffset(animationStartOffset),
30+
),
31+
label = "shake",
32+
)
33+
val rotation by infiniteTransition.animateFloat(
34+
initialValue = -1.5f,
35+
targetValue = 1.5f,
36+
animationSpec = infiniteRepeatable(
37+
animation = tween(animationDurationMillis, easing = LinearEasing),
38+
repeatMode = RepeatMode.Reverse,
39+
initialStartOffset = StartOffset(animationStartOffset),
40+
),
41+
label = "shake",
42+
)
43+
44+
Modifier.graphicsLayer {
45+
scaleX = if (enabled) scaleInfinite else 1f
46+
scaleY = if (enabled) scaleInfinite else 1f
47+
rotationZ = if (enabled) rotation else 0f
48+
}
49+
},
50+
inspectorInfo = debugInspectorInfo {
51+
name = "shake"
52+
properties["enabled"] = enabled
53+
},
54+
)

data/src/main/java/com/shifthackz/aisdv1/data/local/GenerationResultLocalDataSource.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@ internal class GenerationResultLocalDataSource(
2828
.queryById(id)
2929
.map(GenerationResultEntity::mapEntityToDomain)
3030

31+
override fun queryByIdList(idList: List<Long>) = dao
32+
.queryByIdList(idList)
33+
.map(List<GenerationResultEntity>::mapEntityToDomain)
34+
3135
override fun deleteById(id: Long) = dao.deleteById(id)
3236

37+
override fun deleteByIdList(idList: List<Long>) = dao.deleteByIdList(idList)
38+
3339
override fun deleteAll() = dao.deleteAll()
3440
}

data/src/main/java/com/shifthackz/aisdv1/data/repository/GenerationResultRepositoryImpl.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,15 @@ internal class GenerationResultRepositoryImpl(
2828

2929
override fun getById(id: Long) = localDataSource.queryById(id)
3030

31+
override fun getByIds(idList: List<Long>) = localDataSource.queryByIdList(idList)
32+
3133
override fun insert(result: AiGenerationResult) = localDataSource
3234
.insert(result)
3335
.flatMap { id -> exportToMediaStore(result).andThen(Single.just(id)) }
3436

3537
override fun deleteById(id: Long) = localDataSource.deleteById(id)
3638

39+
override fun deleteByIdList(idList: List<Long>) = localDataSource.deleteByIdList(idList)
40+
3741
override fun deleteAll() = localDataSource.deleteAll()
3842
}

domain/src/main/java/com/shifthackz/aisdv1/domain/datasource/GenerationResultDataSource.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ sealed interface GenerationResultDataSource {
1111
fun queryAll(): Single<List<AiGenerationResult>>
1212
fun queryPage(limit: Int, offset: Int): Single<List<AiGenerationResult>>
1313
fun queryById(id: Long): Single<AiGenerationResult>
14+
fun queryByIdList(idList: List<Long>): Single<List<AiGenerationResult>>
1415
fun deleteById(id: Long): Completable
16+
fun deleteByIdList(idList: List<Long>): Completable
1517
fun deleteAll(): Completable
1618
}
1719
}

domain/src/main/java/com/shifthackz/aisdv1/domain/di/DomainModule.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,16 @@ import com.shifthackz.aisdv1.domain.usecase.downloadable.GetLocalAiModelsUseCase
4040
import com.shifthackz.aisdv1.domain.usecase.downloadable.GetLocalAiModelsUseCaseImpl
4141
import com.shifthackz.aisdv1.domain.usecase.downloadable.ObserveLocalAiModelsUseCase
4242
import com.shifthackz.aisdv1.domain.usecase.downloadable.ObserveLocalAiModelsUseCaseImpl
43+
import com.shifthackz.aisdv1.domain.usecase.gallery.DeleteAllGalleryUseCase
44+
import com.shifthackz.aisdv1.domain.usecase.gallery.DeleteAllGalleryUseCaseImpl
4345
import com.shifthackz.aisdv1.domain.usecase.gallery.DeleteGalleryItemUseCase
4446
import com.shifthackz.aisdv1.domain.usecase.gallery.DeleteGalleryItemUseCaseImpl
47+
import com.shifthackz.aisdv1.domain.usecase.gallery.DeleteGalleryItemsUseCase
48+
import com.shifthackz.aisdv1.domain.usecase.gallery.DeleteGalleryItemsUseCaseImpl
4549
import com.shifthackz.aisdv1.domain.usecase.gallery.GetAllGalleryUseCase
4650
import com.shifthackz.aisdv1.domain.usecase.gallery.GetAllGalleryUseCaseImpl
51+
import com.shifthackz.aisdv1.domain.usecase.gallery.GetGalleryItemsUseCase
52+
import com.shifthackz.aisdv1.domain.usecase.gallery.GetGalleryItemsUseCaseImpl
4753
import com.shifthackz.aisdv1.domain.usecase.gallery.GetMediaStoreInfoUseCase
4854
import com.shifthackz.aisdv1.domain.usecase.gallery.GetMediaStoreInfoUseCaseImpl
4955
import com.shifthackz.aisdv1.domain.usecase.generation.GetGenerationResultPagedUseCase
@@ -123,8 +129,11 @@ internal val useCasesModule = module {
123129
factoryOf(::SelectStableDiffusionModelUseCaseImpl) bind SelectStableDiffusionModelUseCase::class
124130
factoryOf(::GetGenerationResultPagedUseCaseImpl) bind GetGenerationResultPagedUseCase::class
125131
factoryOf(::GetAllGalleryUseCaseImpl) bind GetAllGalleryUseCase::class
132+
factoryOf(::GetGalleryItemsUseCaseImpl) bind GetGalleryItemsUseCase::class
126133
factoryOf(::GetGenerationResultUseCaseImpl) bind GetGenerationResultUseCase::class
127134
factoryOf(::DeleteGalleryItemUseCaseImpl) bind DeleteGalleryItemUseCase::class
135+
factoryOf(::DeleteGalleryItemsUseCaseImpl) bind DeleteGalleryItemsUseCase::class
136+
factoryOf(::DeleteAllGalleryUseCaseImpl) bind DeleteAllGalleryUseCase::class
128137
factoryOf(::GetStableDiffusionSamplersUseCaseImpl) bind GetStableDiffusionSamplersUseCase::class
129138
factoryOf(::FetchAndGetLorasUseCaseImpl) bind FetchAndGetLorasUseCase::class
130139
factoryOf(::FetchAndGetHyperNetworksUseCaseImpl) bind FetchAndGetHyperNetworksUseCase::class

domain/src/main/java/com/shifthackz/aisdv1/domain/repository/GenerationResultRepository.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@ interface GenerationResultRepository {
1515

1616
fun getById(id: Long): Single<AiGenerationResult>
1717

18+
fun getByIds(idList: List<Long>): Single<List<AiGenerationResult>>
19+
1820
fun insert(result: AiGenerationResult): Single<Long>
1921

2022
fun deleteById(id: Long): Completable
2123

24+
fun deleteByIdList(idList: List<Long>): Completable
25+
2226
fun deleteAll(): Completable
2327
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.shifthackz.aisdv1.domain.usecase.gallery
2+
3+
import io.reactivex.rxjava3.core.Completable
4+
5+
interface DeleteAllGalleryUseCase {
6+
operator fun invoke(): Completable
7+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.shifthackz.aisdv1.domain.usecase.gallery
2+
3+
import com.shifthackz.aisdv1.domain.repository.GenerationResultRepository
4+
import io.reactivex.rxjava3.core.Completable
5+
6+
internal class DeleteAllGalleryUseCaseImpl(
7+
private val generationResultRepository: GenerationResultRepository,
8+
) : DeleteAllGalleryUseCase {
9+
10+
override fun invoke(): Completable = generationResultRepository.deleteAll()
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.shifthackz.aisdv1.domain.usecase.gallery
2+
3+
import io.reactivex.rxjava3.core.Completable
4+
5+
interface DeleteGalleryItemsUseCase {
6+
operator fun invoke(ids: List<Long>): Completable
7+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.shifthackz.aisdv1.domain.usecase.gallery
2+
3+
import com.shifthackz.aisdv1.domain.repository.GenerationResultRepository
4+
import io.reactivex.rxjava3.core.Completable
5+
6+
internal class DeleteGalleryItemsUseCaseImpl(
7+
private val generationResultRepository: GenerationResultRepository,
8+
) : DeleteGalleryItemsUseCase {
9+
10+
override fun invoke(ids: List<Long>): Completable = generationResultRepository.deleteByIdList(ids)
11+
}

0 commit comments

Comments
 (0)