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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ open: **a second build under the same version goes under the already cut
heading, not back under `Unreleased`.** Date the heading and add its compare link
once the version tag exists.

## [Unreleased]

### Added

- A zip file opens and lists what is inside. Tapping an entry shows it.
- Photos and text files the reader used to refuse now open.

### Changed

- A file that will not open says so, and offers to write to us when something
went wrong on our side.
- The app no longer offers itself for music and films.

## [1.42]

### Added
Expand Down
3 changes: 3 additions & 0 deletions OpenDocumentReader/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ enum Constants {
/// Which of the house ad's rotations comes next.
static let key_house_ad_index = "houseAdIndex"

/// The address the "file will not open" message names.
static let supportEmail = "support@opendocument.app"

/// ODR Pro on the App Store. This is the *paid* app: on iOS that is `at.tomtasche.reader`,
/// while on Android the same bundle id names the free one.
static let proAppStoreId = 1_452_061_743
Expand Down
28 changes: 15 additions & 13 deletions OpenDocumentReader/CoreWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,13 @@ private func selectViews(_ views: [HtmlView], _ documentType: DocumentType) -> [
}
}

/// A csv is a *text* file to odrcore that also loads as a spreadsheet, so it
/// answers `isDocumentFile` with false and `asDocumentFile()` fails on it.
private func isCsv(_ file: DecodedFile) -> Bool { file.fileType == .commaSeparatedValues }

@objc final class CoreWrapper: NSObject {
@objc private(set) var pageNames: [String] = []
@objc private(set) var pageURLs: [URL] = []

/// Whether odrcore saw only a container, so the page is a listing of what is inside it.
@objc private(set) var isArchive = false

/// Whether `backTranslate` has a document to apply an edit to. Only a
/// document that said it takes one is kept, so having it *is* the answer.
@objc var isEditable: Bool { lock.withLock { document != nil } }
Expand All @@ -105,6 +104,7 @@ private func isCsv(_ file: DecodedFile) -> Bool { file.fileType == .commaSeparat
pageNames = []
pageURLs = []
document = nil
isArchive = false

let fileTypes = (try? DecodedFile.listFileTypes(path: inputPath)) ?? []
guard !fileTypes.isEmpty else {
Expand All @@ -126,11 +126,14 @@ private func isCsv(_ file: DecodedFile) -> Bool { file.fileType == .commaSeparat
}
}

// odrcore also translates images, media and fonts, but only into an
// `<img>` or a `<video>` the web view decodes anyway. Those go to the
// system instead, through the fallback in `DocumentViewController`.
guard file.isDocumentFile || file.isPdfFile || isCsv(file) else {
throw coreWrapperError(.unsupportedFileType, "not a document, a pdf or a csv")
guard Odr.capabilities(fileType: file.fileType).translateHtml else {
throw coreWrapperError(.unsupportedFileType, "odrcore does not render this file type")
}

// odrcore calls a file it recognises as nothing else text, so an unnamed
// charset means the bytes are not text at all
if file.isTextFile, (try? file.asTextFile())?.charset == nil {
throw coreWrapperError(.unsupportedFileType, "odrcore could not name a charset")
}

// the same answers OpenDocument.droid gives odrcore, so a document is
Expand Down Expand Up @@ -170,10 +173,8 @@ private func isCsv(_ file: DecodedFile) -> Bool { file.fileType == .commaSeparat
service = try HtmlTranslator.translate(
document: document, cachePath: cachePath, config: config)
} else {
// a csv and a pdf have no document behind them to open or to edit.
// `.unknown` keeps the combined view for both; not `.spreadsheet`,
// though a csv is one, because that asks for a tab per sheet and a
// csv's single sheet is called "csv"
// nothing to edit, and `.unknown` keeps the single view each of
// these has - `.spreadsheet` would ask for a tab per sheet
documentType = .unknown
openedDocument = nil
service = try HtmlTranslator.translate(
Expand All @@ -193,6 +194,7 @@ private func isCsv(_ file: DecodedFile) -> Bool { file.fileType == .commaSeparat
// a document whose pages were never served
self.document = openedDocument

isArchive = file.isArchiveFile
pageNames = views.map(\.name)
pageURLs = views.map { base.appendingPathComponent($0.path) }
}
Expand Down
4 changes: 4 additions & 0 deletions OpenDocumentReader/Document.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class Document: UIDocument {
public var webview: WKWebView?

public var isOdf = false
/// Whether the page is a listing of an archive - see `CoreWrapper.isArchive`.
public var isArchive = false
/// Whether the menu should offer to edit this one - see `CoreWrapper.isEditable`.
public var isEditable = false
private var wasPageCountAnnounced = false
Expand All @@ -62,6 +64,7 @@ class Document: UIDocument {
loadProgress.completedUnitCount = 2

isOdf = false
isArchive = false
isEditable = false
result = nil
pageURLs = nil
Expand Down Expand Up @@ -91,6 +94,7 @@ class Document: UIDocument {
}

isOdf = true
isArchive = coreWrapper.isArchive
isEditable = coreWrapper.isEditable

loadProgress.completedUnitCount = loadProgress.totalUnitCount
Expand Down
Loading