Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
e5f7c94
Storacha Initial Commit
prathieshna May 29, 2025
15618ac
Deleting unnecessary file
prathieshna May 29, 2025
a73f6c7
Added QR Functionality for the Adding Access
Jun 3, 2025
fee8731
Partial API Implementation
Jun 25, 2025
1266019
Partial API Implementation
Jul 6, 2025
5ac136c
Partial API Implementation
Jul 17, 2025
ef50538
Car File Generation Kotlin POC
Jul 18, 2025
7caf723
Updated Login + Car file generation POC
Aug 6, 2025
efaff3c
Merge remote-tracking branch 'origin/next' into feature/storacha-next
Elelan Aug 11, 2025
6525e3b
chore: update dependencies and clean up build configuration
Elelan Aug 12, 2025
329eda5
Merge remote-tracking branch 'origin/next' into feature/storacha-next
Elelan Aug 12, 2025
abfae13
Updated Login + Car file generation POC
Aug 14, 2025
cf08757
chore: update Compose and Fragment versions to latest stable releases
Elelan Aug 14, 2025
c6cd7b0
Working carfile creater
Aug 14, 2025
bae9c18
Merge remote-tracking branch 'origin/next' into feature/storacha-next
Elelan Aug 15, 2025
be6f058
Merge remote-tracking branch 'origin/feature/storacha' into feature/s…
Elelan Aug 15, 2025
54450f0
Update Storacha service and dependencies
Elelan Aug 19, 2025
348584c
Applied edge-to-edge insets to StorachaAccountDetailsFragment
Elelan Aug 19, 2025
93e7db1
Fixed Issues
Aug 25, 2025
94d2069
Added Revoke Prompt and Navigation Drawer Logic for Storacha
Aug 27, 2025
6c16663
QR code, Scanning, Revoke API fixes
Aug 27, 2025
19798e4
Merge branch 'feature/storacha' into feature/storacha-next
prathieshna Aug 27, 2025
d7ec26c
Merge pull request #704 from OpenArchive/feature/storacha-next
prathieshna Aug 27, 2025
44abafc
Fixed the is Admin based navigation
Aug 28, 2025
2585c4a
Account Details and Navigation Fixes.
Aug 28, 2025
7da6c2f
Fixed Minor Issues
Sep 1, 2025
5cef277
Merge branch 'next' into feature/storacha-next
Elelan Sep 10, 2025
c0c85ea
Partically Working CID
Sep 10, 2025
035cd54
Small File Uploads Working
Sep 10, 2025
847cf89
File thumbnails has been added, File names extracted from IPFS.
Sep 10, 2025
5eae3f4
Merge branch 'feature/storacha' into feature/storacha-next
Elelan Sep 11, 2025
d98b5e2
Merge branch 'next' into feature/storacha-next
Elelan Sep 11, 2025
953e691
Merge pull request #708 from OpenArchive/feature/storacha-next
prathieshna Sep 11, 2025
57c0511
corrected version name for core-ktx in libs.versions.toml
Elelan Sep 11, 2025
284e251
Merge pull request #709 from OpenArchive/feature/storacha-next
prathieshna Sep 11, 2025
de4d5b8
Fixed minor issue
Sep 16, 2025
90d8434
Fixed minor issues related to Email polling and keyboard hiding issues.
Sep 16, 2025
2fcef2d
Logout navigation issue fixed.
Sep 16, 2025
1c9def1
Refactor - Untested
Sep 17, 2025
a82868f
Refactor - Fixes
Sep 18, 2025
8a551be
UI Fixes
Sep 21, 2025
bf71546
Conflicts resolved
Sep 21, 2025
c459fba
storacha: enhance account details and upload robustness
Sep 22, 2025
04262ba
Added Picker but Camera is not working yet - WIP
Sep 22, 2025
0b58423
Revert "Added Picker but Camera is not working yet - WIP"
Sep 22, 2025
41b5635
storacha: make sessionId optional
Sep 26, 2025
6ad06f7
Implemented pull-to-refresh for Storacha media and spaces
Sep 26, 2025
768fa49
Refactor: Storacha isAdmin flag integration and media list pagination…
Sep 30, 2025
57ebca4
conflicts resolved
Oct 6, 2025
b7dbc9b
Resolve merge conflicts in strings.xml
Oct 6, 2025
9fb91fb
Storacha staging URL update
Oct 9, 2025
efe1826
Updated Storacha UI/UX and strings
Oct 9, 2025
5ebc2db
Storacha UI/UX fixes and improvements
Oct 9, 2025
c272916
feat: add support for PDF and other document types
Oct 9, 2025
362d36c
Storacha upload fixes and improvements
Oct 9, 2025
b78d7fd
feat: Add email validation to Storacha login
Oct 9, 2025
21d3a14
Added change email option to verification screen
Oct 13, 2025
feb5880
Implemented Storacha DID validation and login loading state
Oct 21, 2025
9d6dfd6
Updated video and PDF file icons
Oct 21, 2025
11e1853
Refactored Storacha access logic with StorachaHelper
Oct 21, 2025
84c7222
feat: Use modern camera picker
Oct 21, 2025
fa77338
Storacha edge-to-edge UI improvements
Oct 23, 2025
161b4ae
removed error from tvDid
Oct 23, 2025
26a628d
Refactored Storacha UI and moved StorachaAccount model
Oct 23, 2025
bd00623
Refactored CAR file handling to use file streaming
Oct 23, 2025
f89a38c
Fixed OOM error during large file uploads to Storacha
Oct 23, 2025
3aa2a43
feat: Clean up previous failed uploads
Oct 23, 2025
1eea33a
refactored button color usage
Oct 23, 2025
d3827ad
refactor: improved Storacha session handling
Oct 28, 2025
610e58a
feat: Improve DID input validation and UX
Oct 28, 2025
7fb9c7c
added storacha content picker
Oct 28, 2025
2e37bcb
Refactored Storacha UI and UX
Nov 19, 2025
fe842c6
Refactor: remove Google Drive integration
Nov 19, 2025
349a809
Fixed camera uploads and file handling
Nov 19, 2025
813e138
Merge remote-tracking branch 'origin/next' into feature/storacha
Nov 19, 2025
5ccb5bb
Fix: escape apostrophes in Ukrainian and Turkish strings
Nov 19, 2025
17e0f62
refactored client QR and email verification UI/UX
Nov 19, 2025
5c674c6
Bumped version to 4.0.8
Nov 19, 2025
abc7738
refactor: Update icons and improve UX text
Nov 19, 2025
dd968d7
feat: Integrate custom and modern camera launchers
Nov 19, 2025
82c6a30
Added `useCleanFilenames` option to CameraConfig
Nov 19, 2025
b8eebdb
updated color usage in Storacha UI resources
Nov 21, 2025
31d2d96
Bumped version to 4.0.10
Nov 22, 2025
7205615
optimized pagination logic and duplicate filtering in StorachaMediaVi…
Nov 22, 2025
2a87784
refactored: StorachaMediaViewModel pagination logic
Nov 25, 2025
b9ee380
Bumping version to 4.0.12
Nov 25, 2025
87432f7
Merge branch 'next' into feature/storacha
Nov 26, 2025
27c5452
Bumping version to 4.0.13
Nov 26, 2025
5b92e12
storacha string externalization
Nov 27, 2025
5e3405a
Merged with next branch
Nov 29, 2025
0f5e9c9
refactor: Code cleanup and dependency upgrades
Nov 29, 2025
0663030
refactored camera controls layout and updated "Done" button UI
Nov 29, 2025
e17cf82
Bumping version code and name
Nov 29, 2025
ec1d2b8
Merge branch 'next' into feature/storacha
Dec 2, 2025
ca0b0ff
Merge remote-tracking branch 'origin/next' into feature/storacha
Dec 2, 2025
37ad2dd
feat: Bump version code and name
Dec 2, 2025
ce133d8
fix: escaped apostrophes in Ukrainian and cleaned up Turkish strings
Dec 2, 2025
d7e1b90
feat: Bump version code to 30027
Dec 2, 2025
0496fe8
Merge remote-tracking branch 'origin/next' into feature/storacha
Dec 5, 2025
d07cad7
Merge branch 'next' into feature/storacha
Dec 10, 2025
575a4fd
feat: Launch Snowbird in its own activity
Dec 10, 2025
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
20 changes: 15 additions & 5 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ android {
applicationId = "net.opendasharchive.openarchive"
minSdk = 29
targetSdk = 36
versionCode = 30021
versionName = "4.0.3"
versionCode = 30027
versionName = "4.0.4"
multiDexEnabled = true
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Expand Down Expand Up @@ -130,9 +130,13 @@ android {
resources {
excludes.addAll(
listOf(
"META-INF/LICENSE.txt", "META-INF/NOTICE.txt", "META-INF/LICENSE",
"META-INF/NOTICE", "META-INF/DEPENDENCIES", "LICENSE.txt"
)
"META-INF/LICENSE.txt",
"META-INF/NOTICE.txt",
"META-INF/LICENSE",
"META-INF/NOTICE",
"META-INF/DEPENDENCIES",
"LICENSE.txt",
),
)
}
}
Expand Down Expand Up @@ -241,12 +245,14 @@ dependencies {
implementation(libs.retrofit.gson)
implementation(libs.retrofit.kotlinx.serialization)
implementation(libs.guardianproject.sardine)
implementation(libs.jsoup)

// Images & Media
implementation(libs.coil)
implementation(libs.coil.compose)
implementation(libs.coil.video)
implementation(libs.coil.network)
implementation(libs.picasso)

// CameraX
implementation(libs.androidx.camera.core)
Expand All @@ -256,6 +262,10 @@ dependencies {
implementation(libs.androidx.camera.view)
implementation(libs.androidx.camera.extensions)

// Barcode Scanning
implementation(libs.zxing.core)
implementation(libs.zxing.android.embedded)

// Media3 - ExoPlayer
implementation(libs.androidx.media3.exoplayer)
implementation(libs.androidx.media3.ui)
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
-->

<application
android:usesCleartextTraffic="true"
android:name=".SaveApp"
android:allowBackup="false"
android:dataExtractionRules="@xml/data_extraction_rules"
Expand Down Expand Up @@ -203,6 +204,12 @@
android:theme="@style/SaveAppTheme.NoActionBar"
android:windowSoftInputMode="stateHidden" />

<activity
android:name=".services.storacha.PortraitCaptureActivity"
android:screenOrientation="portrait"
android:theme="@style/zxing_CaptureTheme"
android:exported="false" />

<meta-data
android:name="DOMAIN_PACKAGE_NAME"
android:value="net.opendasharchive.openarchive.db" />
Expand Down
15 changes: 8 additions & 7 deletions app/src/main/java/net/opendasharchive/openarchive/SaveApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,18 @@ package net.opendasharchive.openarchive

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.UiModeManager
import android.content.Context
import android.os.Build
import androidx.appcompat.app.AppCompatDelegate
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import coil3.ImageLoader
import coil3.PlatformContext
import coil3.SingletonImageLoader
import coil3.video.VideoFrameDecoder
import com.orm.SugarApp
import info.guardianproject.netcipher.proxy.OrbotHelper
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import net.opendasharchive.openarchive.analytics.api.AnalyticsManager
import net.opendasharchive.openarchive.analytics.api.session.SessionTracker
Expand All @@ -27,10 +25,11 @@ import net.opendasharchive.openarchive.core.di.retrofitModule
import net.opendasharchive.openarchive.core.di.unixSocketModule
import net.opendasharchive.openarchive.core.logger.AppLogger
import net.opendasharchive.openarchive.features.settings.passcode.PasscodeManager
import net.opendasharchive.openarchive.services.storacha.di.storachaModule
import net.opendasharchive.openarchive.util.Prefs
import org.koin.android.ext.android.inject
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.android.ext.android.inject
import org.koin.core.context.startKoin
import org.koin.core.logger.Level

Expand Down Expand Up @@ -71,6 +70,8 @@ class SaveApp : SugarApp(), SingletonImageLoader.Factory, DefaultLifecycleObserv
retrofitModule,
unixSocketModule,
passcodeModule,
storachaModule,
passcodeModule,
analyticsModule(
mixpanelToken = getString(R.string.mixpanel_key),
cleanInsightsConsentChecker = { CleanInsightsManager.hasConsent() }
Expand Down
106 changes: 62 additions & 44 deletions app/src/main/java/net/opendasharchive/openarchive/db/Space.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
private var licenseUrl: String? = null,
// private var chunking: Boolean? = null
) : SugarRecord() {

constructor(type: Type) : this() {
tType = type

Expand All @@ -55,25 +54,33 @@
}

Type.RAVEN -> "Raven"
Type.STORACHA -> "Storacha Service"
}
}

enum class Type(val id: Int, val friendlyName: String) {
enum class Type(
val id: Int,
val friendlyName: String,
) {
WEBDAV(0, "Private Server"),
INTERNET_ARCHIVE(1, IaConduit.NAME),
RAVEN(5, "DWeb Storage"),
STORACHA(7, "Storacha Service"),

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.
}

enum class IconStyle {
SOLID, OUTLINE
SOLID,
OUTLINE,
}

companion object {
fun getAll(): Iterator<Space> {
return findAll(Space::class.java)
}
fun getAll(): Iterator<Space> = findAll(Space::class.java)

fun get(type: Type, host: String? = null, username: String? = null): List<Space> {
fun get(
type: Type,
host: String? = null,
username: String? = null,
): List<Space> {
var whereClause = "type = ?"
val whereArgs = mutableListOf(type.id.toString())

Expand All @@ -88,14 +95,20 @@
}

return find(
Space::class.java, whereClause, whereArgs.toTypedArray(),
null, null, null
Space::class.java,
whereClause,
whereArgs.toTypedArray(),
null,
null,
null,
)
}

fun has(type: Type, host: String? = null, username: String? = null): Boolean {
return get(type, host, username).isNotEmpty()
}
fun has(
type: Type,
host: String? = null,
username: String? = null,
): Boolean = get(type, host, username).isNotEmpty()

var current: Space?
get() {
Expand All @@ -107,9 +120,7 @@
Prefs.currentSpaceId = value?.id ?: -1
}

fun get(id: Long): Space? {
return findById(Space::class.java, id)
}
fun get(id: Long): Space? = findById(Space::class.java, id)

fun navigate(activity: AppCompatActivity) {
if (getAll().hasNext()) {
Expand Down Expand Up @@ -161,59 +172,67 @@
// }

val projects: List<Project>
get() = find(
Project::class.java,
"space_id = ? AND NOT archived",
arrayOf(id.toString()),
null,
"id DESC",
null
)
get() =
find(
Project::class.java,
"space_id = ? AND NOT archived",
arrayOf(id.toString()),
null,
"id DESC",
null,
)

val archivedProjects: List<Project>
get() = find(
Project::class.java,
"space_id = ? AND archived",
arrayOf(id.toString()),
null,
"id DESC",
null
)
get() =
find(
Project::class.java,
"space_id = ? AND archived",
arrayOf(id.toString()),
null,
"id DESC",
null,
)

fun hasProject(description: String): Boolean {
// Cannot use `count` from Kotlin due to strange <T> in method signature.
return find(
Project::class.java,
"space_id = ? AND description = ?",
id.toString(),
description
description,
).isNotEmpty()
}

fun getAvatar(context: Context): Drawable? {


return when (tType) {
fun getAvatar(context: Context): Drawable? =
when (tType) {
Type.WEBDAV -> ContextCompat.getDrawable(context, R.drawable.ic_private_server)

Type.INTERNET_ARCHIVE -> ContextCompat.getDrawable(context, R.drawable.ic_internet_archive)
Type.INTERNET_ARCHIVE ->
ContextCompat.getDrawable(
context,
R.drawable.ic_internet_archive,
)

Type.RAVEN -> ContextCompat.getDrawable(context, R.drawable.ic_dweb)

Type.STORACHA ->
ContextCompat.getDrawable(
context,
R.drawable.storacha,
)
}
}

@Composable
fun getAvatar(): Painter {

return when (tType) {
fun getAvatar(): Painter =
when (tType) {
Type.WEBDAV -> painterResource(R.drawable.ic_space_private_server)

Type.INTERNET_ARCHIVE -> painterResource(R.drawable.ic_space_interent_archive)

Type.RAVEN -> painterResource(R.drawable.ic_space_dweb)

Type.STORACHA -> painterResource(R.drawable.storacha)
}
}

fun setAvatar(view: ImageView) {
when (tType) {
Expand All @@ -223,7 +242,6 @@

else -> {
view.setImageDrawable(getAvatar(view.context))

}
}
}
Expand All @@ -235,4 +253,4 @@

return super.delete()
}
}
}
Loading