Skip to content
Merged
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
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- PDF text selection and copying
- Option for dark PDF pages
- Option for horizontal PDF scrolling
- PDF, DOCX, and HTML text search ([#87])
- PDF table of contents ([#77])
- Option to hide floating PDF page numbers ([#79])
- Reopen to edit button for read-only files ([#71])
- Support for editing more text formats ([#76])

### Fixed

- Fixed files opened from other apps missing from Recent apps ([#73])
- Fixed CSV editing for files opened from other apps ([#70])

## [1.0.1] - 2026-08-01
### Changed
- Updated translations
Expand All @@ -17,6 +33,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Initial release

[#70]: https://github.com/FossifyOrg/Documents/issues/70
[#71]: https://github.com/FossifyOrg/Documents/issues/71
[#73]: https://github.com/FossifyOrg/Documents/issues/73
[#76]: https://github.com/FossifyOrg/Documents/issues/76
[#77]: https://github.com/FossifyOrg/Documents/issues/77
[#79]: https://github.com/FossifyOrg/Documents/issues/79
[#87]: https://github.com/FossifyOrg/Documents/issues/87

[Unreleased]: https://github.com/FossifyOrg/Documents/compare/1.0.1...HEAD
[1.0.1]: https://github.com/FossifyOrg/Documents/compare/1.0.0...1.0.1
[1.0.0]: https://github.com/FossifyOrg/Documents/releases/tag/1.0.0
6 changes: 6 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
-keep class com.shockwave.** { *; }

# Commons includes optional fingerprint UI that Documents does not use.
-dontwarn android.hardware.fingerprint.FingerprintManager
-dontwarn android.hardware.fingerprint.FingerprintManager$AuthenticationCallback
-dontwarn android.hardware.fingerprint.FingerprintManager$AuthenticationResult
-dontwarn android.hardware.fingerprint.FingerprintManager$CryptoObject
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@

<activity
android:name=".activities.DocumentOpenActivity"
android:excludeFromRecents="true"
android:exported="true"
android:theme="@style/TranslucentTheme">
<intent-filter>
Expand All @@ -75,6 +74,8 @@
<data android:mimeType="application/yaml" />
<data android:mimeType="application/x-yaml" />
<data android:mimeType="application/toml" />
<data android:mimeType="application/x-tex" />
<data android:mimeType="application/octet-stream" />
</intent-filter>
</activity>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.app.Activity
import android.content.Intent
import android.os.Bundle
import org.fossify.commons.extensions.getFilenameFromUri
import org.fossify.commons.extensions.getMimeTypeFromUri
import org.fossify.commons.extensions.toast
import org.fossify.documents.R
import org.fossify.documents.models.DocumentKind
Expand All @@ -18,7 +17,16 @@ class DocumentOpenActivity : Activity() {
return
}

val destination = when (val kind = DocumentKind.fromName(getFilenameFromUri(uri), getMimeTypeFromUri(uri))) {
val suppliedType = intent.type.orEmpty().substringBefore(';').trim().lowercase()
val mimeType = if (suppliedType.isBlank() || suppliedType == "application/octet-stream" ||
suppliedType.endsWith("/*")
) {
val providerType = contentResolver.getType(uri).orEmpty().substringBefore(';').trim().lowercase()
providerType.takeUnless { it.isBlank() || it == "application/octet-stream" } ?: suppliedType
} else {
suppliedType
}
val destination = when (val kind = DocumentKind.fromName(getFilenameFromUri(uri), mimeType)) {
DocumentKind.PDF -> Intent(this, PDFViewerActivity::class.java).apply { data = uri }
DocumentKind.TEXT,
DocumentKind.MARKDOWN -> TextDocumentActivity.newIntent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ import android.net.Uri
import android.os.Bundle
import android.print.PrintAttributes
import android.print.PrintManager
import android.provider.DocumentsContract
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.getValue
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
Expand All @@ -25,8 +30,18 @@ import org.fossify.documents.extensions.config
import org.fossify.documents.helpers.PdfDocumentAdapter
import org.fossify.documents.ui.screens.PdfDocumentScreen
import org.fossify.documents.ui.theme.DocumentsAppThemeSurface
import org.fossify.documents.viewmodels.PdfDocumentViewModel

class PDFViewerActivity : BaseComposeActivity() {
private val preferences by lazy { config }
private val viewModel by lazy { ViewModelProvider(this)[PdfDocumentViewModel::class.java] }
private val createCopy = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val destination = result.data?.data
val source = intent.data
if (result.resultCode == RESULT_OK && destination != null && source != null) {
viewModel.saveCopy(source, destination, result.data?.flags ?: 0)
}
}
private val pageUpdates = Channel<Int>(Channel.CONFLATED)

override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -49,9 +64,19 @@ class PDFViewerActivity : BaseComposeActivity() {
}
}

lifecycleScope.launch {
viewModel.copyMessages.collect { toast(it) }
}

enableEdgeToEdgeSimple()
setContent {
DocumentsAppThemeSurface {
val nightMode by preferences.pdfDarkPagesFlow
.collectAsStateWithLifecycle(preferences.pdfDarkPages)
val showPageIndicator by preferences.pdfPageIndicatorFlow
.collectAsStateWithLifecycle(preferences.pdfPageIndicator)
val horizontalPaging by preferences.pdfHorizontalPagingFlow
.collectAsStateWithLifecycle(preferences.pdfHorizontalPaging)
PdfDocumentScreen(
uri = uri,
title = title,
Expand All @@ -65,14 +90,39 @@ class PDFViewerActivity : BaseComposeActivity() {
repository.rememberDocument(uri, intent.flags)
}
},
onSaveCopy = { requestSaveCopy(uri, title) },
isCopying = viewModel.isCopying,
onPrint = { printPdf(uri, title) },
onOpenWith = { openWith(uri) },
onFullscreenChange = ::setFullscreen,
nightMode = nightMode,
showPageIndicator = showPageIndicator,
horizontalPaging = horizontalPaging,
onNightModeChange = { preferences.pdfDarkPages = it },
onSettings = { startActivity(Intent(this, SettingsActivity::class.java)) },
)
}
}
}

private fun requestSaveCopy(uri: Uri, title: String) {
val request = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/pdf"
putExtra(Intent.EXTRA_TITLE, title)
putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri)
addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION or
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
)
}
try {
createCopy.launch(request)
} catch (_: ActivityNotFoundException) {
toast(org.fossify.commons.R.string.no_app_found)
}
}

private fun setFullscreen(fullscreen: Boolean) {
WindowCompat.getInsetsController(window, window.decorView).apply {
systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ class SettingsActivity : BaseComposeActivity() {
.collectAsStateWithLifecycle(preferences.showCheckmarksOnSwitches)
val rememberPdfPage by preferences.rememberPdfPageFlow
.collectAsStateWithLifecycle(preferences.rememberPdfPage)
val horizontalPdfPaging by preferences.pdfHorizontalPagingFlow
.collectAsStateWithLifecycle(preferences.pdfHorizontalPaging)
val showPdfPageIndicator by preferences.pdfPageIndicatorFlow
.collectAsStateWithLifecycle(preferences.pdfPageIndicator)
val showFileLocations by preferences.showFileLocationsFlow
.collectAsStateWithLifecycle(preferences.showFileLocations)
val displayLanguage = remember { Locale.getDefault().displayLanguage }
Expand All @@ -51,6 +55,8 @@ class SettingsActivity : BaseComposeActivity() {
isUseEnglishChecked = useEnglishFlow,
isShowingCheckmarksOnSwitches = showCheckmarksOnSwitches,
rememberPdfPage = rememberPdfPage,
horizontalPdfPaging = horizontalPdfPaging,
showPdfPageIndicator = showPdfPageIndicator,
showFileLocations = showFileLocations,
onUseEnglishPress = { isChecked ->
preferences.useEnglish = isChecked
Expand All @@ -60,6 +66,12 @@ class SettingsActivity : BaseComposeActivity() {
onRememberPdfPageChange = { checked ->
preferences.rememberPdfPage = checked
},
onHorizontalPdfPagingChange = { checked ->
preferences.pdfHorizontalPaging = checked
},
onPdfPageIndicatorChange = { checked ->
preferences.pdfPageIndicator = checked
},
onShowFileLocationsChange = { checked ->
preferences.showFileLocations = checked
},
Expand Down
Loading
Loading