ddcd68b4b7
The selection bar offered Copy and Move, which only filled an in-app clipboard; the destination picker then lived behind an overflow menu, and Paste in the top bar. That made a copy a two-step detour through another folder - the thing M16's picker exists to avoid. - The bar's two verbs are now Copy to… and Cut to…, both opening the destination picker. - The clipboard state, Paste here, and the overflow's duplicate Copy to… / Move to… are removed. The picker's cut title and confirm are Cut to… / Cut here. - A copy still keeps the selection for a second destination; a cut clears it. Conflicts still ask before overwriting, naming the picked folder. - Five clipboard tests are removed; the mark, restart and undo tests now use the picker. BrowserTopBar's search and overflow sections are extracted so its two new detekt findings are fixed rather than baselined. Driven on the Xiaomi phone: Copy to… copied 120 x 16 MB through Internal storage -> AADemo -> Target and reported Copied 121 items to Target; Cut to… moved file001.bin and offered Undo; a name in the way raised Items already exist here; the top-bar overflow has no Paste. The foreground-service video was re-recorded against the new bar at 16.1 s. Verified: ./tools/verify.sh green, the code map current, 426 unit tests pass, and the video decodes as H.264 1080x2400 with no audio.
147 lines
8.2 KiB
Markdown
147 lines
8.2 KiB
Markdown
# Release notes
|
|
|
|
The copy a buyer reads *before* installing, as opposed to [CHANGELOG](../CHANGELOG.md), which is the
|
|
reasoning for whoever maintains the app. Two lengths live here:
|
|
|
|
- **Play Console → What's new** — plain text, **500 characters per language**, no Markdown and no
|
|
bullets (Play renders neither), measured rather than estimated.
|
|
- **The longer announcement** — for a website, a forum post or a GitHub release, where the limit is
|
|
the reader's patience rather than a Console field.
|
|
|
|
The source of truth for *what* changed is the changelog, and the source of truth for *what the app
|
|
claims* is the [README](../README.md) and [STORE_LISTING](STORE_LISTING.md). This file only chooses
|
|
which of those facts a new user should hear first.
|
|
|
|
## Writing the next one
|
|
|
|
1. **Version.** `versionName` and `versionCode` are in `app/build.gradle.kts`; the latter must be
|
|
higher than every previous upload. The first release is `1.0.0` / `1`.
|
|
2. **Changelog first.** Move the entries out of `## [Unreleased]` into a
|
|
`## [1.0.0] - YYYY-MM-DD` heading, so this file and the changelog cannot describe different
|
|
builds.
|
|
3. **Then the Play field.** Say what a user can now do that they could not before — never what the
|
|
code did. A first release describes the app instead of a diff.
|
|
4. **Measure it.** Play counts characters, line breaks included:
|
|
|
|
```bash
|
|
python3 -c "print(len(open('/tmp/whats-new.txt').read().strip()))"
|
|
```
|
|
|
|
5. **Quote nothing that a device has not shown.** A limitation belongs in the announcement only if
|
|
it is already in the README's *Known limitations*; if it is not, the README is what needs fixing.
|
|
|
|
---
|
|
|
|
## 1.0.0 — first release
|
|
|
|
### Play Console → What's new (500 characters max)
|
|
|
|
```
|
|
Plain Files is here: a file manager with no ads, no account and no internet permission, so nothing leaves your device.
|
|
|
|
Browse internal storage, SD cards and USB drives. Copy, move, rename and delete files; undo a delete, rename or move; search everywhere; find duplicates; unpack ZIP, TAR, GZ, BZ2, XZ and 7z; star the folders you use; and read images, video, PDFs and text inside the app.
|
|
|
|
One purchase, every feature. No tracking, no subscription.
|
|
```
|
|
|
|
**Measured: 450 characters** (including the two blank lines between paragraphs). The remaining
|
|
headroom is deliberate: it leaves room for a sentence about a fix without rewriting the whole field.
|
|
|
|
Why this shape: the first two sentences are the claim no competitor in the survey makes — no ads and
|
|
**no `INTERNET` permission** — and the middle one is the proof that it is still a file manager. The
|
|
verbs are the ones people use ("copy, move, rename, delete"), not the app's internal names. Nothing
|
|
here is a superlative, an emoji, or the word *free*: the app is paid, and a headline implying
|
|
otherwise is both misleading and against Play's editorial policy.
|
|
|
|
### The longer announcement
|
|
|
|
> Plain Files 1.0.0 is available for Android 8.0 and later. One purchase, no subscription, no ads,
|
|
> and no way for the app to send anything off the device — because it does not hold the network
|
|
> permission at all.
|
|
|
|
#### What it does
|
|
|
|
**Browsing.** Internal storage, SD cards and USB drives side by side. List or grid, sorted by
|
|
name — `file2` before `file10` — size, date or type; hidden files on request; breadcrumbs; and a
|
|
search that either stays in the folder you are in or looks everywhere through an on-device index
|
|
which says how current its answer is.
|
|
|
|
**Moving files around.** Copy, move, rename and delete one item or many. **Copy to…** and **Cut
|
|
to…** open a folder picker — volumes first, then one level at a time — and start the transfer into
|
|
that folder without taking you out of the one you are standing in. A finished copy says
|
|
*Copied to folder* and offers **Show**. A name that already exists asks before overwriting, and a
|
|
batch that cannot succeed is refused as a whole rather than performed until it
|
|
hits the problem. The rows an operation produced carry a dot until you next open that folder, so
|
|
"what did that 4 GB copy do?" has an answer even when the destination was elsewhere.
|
|
|
|
**Undo, and a trash that explains itself.** A delete is a move into a hidden `.plainfiles-trash`
|
|
folder on the same volume, kept for **24 hours**; the Trash screen states that window, offers
|
|
**Empty trash** behind one question, and sweeps expired batches when you open it. Rename and move
|
|
offer undo as well.
|
|
|
|
**Renaming a batch.** Select several files and Rename opens a pattern rather than the single-file
|
|
dialog: one name, the number to start at, and a live preview of the names it will produce. The
|
|
numbering **continues the folder's own series** — `Holiday (1)` and `Holiday (2)` already there make
|
|
the next batch start at 3 — because a batch rename that always starts at 1 is useless the second
|
|
time it is used. A name in the way blocks the batch and is named as it is typed.
|
|
|
|
**Finding things.** The duplicate finder compares size, then the head of every candidate, then the
|
|
survivors in full — never a name or a date. The storage-usage view measures every folder and ranks
|
|
it largest first, so the folder eating the card is the one at the top.
|
|
|
|
**Looking at files.** Image, text, PDF, media and archive viewers, and an APK's own details read
|
|
without installing it. Thumbnails show the picture, and a **video shows a frame of itself** rather
|
|
than a film icon. An archive can be read without extracting it first, with entry names checked
|
|
against zip-slip.
|
|
|
|
**Archives.** Create ZIP; extract ZIP, TAR, TAR.GZ, TAR.BZ2, TAR.XZ, GZ, BZ2, XZ and 7z. When
|
|
compressing, you choose the name and whether to compress at all: for copying a collection to a
|
|
computer, storing the files as they are takes one pass and is still an ordinary archive.
|
|
|
|
**Working with other apps.** Plain Files can receive a share from anywhere and appear in another
|
|
app's file chooser. Neither costs a permission.
|
|
|
|
**Tablets and large windows.** At expanded width the screen splits into two panes: the folder list
|
|
on the left, and the contents — or a preview and the details — of the folder or file you pick on the
|
|
right.
|
|
|
|
**Shortcuts.** Long-press the app icon for **Images**, **Recent** and **Trash**.
|
|
|
|
#### What it deliberately does not do
|
|
|
|
- **No cloud storage, network shares, FTP/SFTP/WebDAV or web server.** Every one of those needs
|
|
`INTERNET`, which is the single permission this app refuses to hold. That is the product, not a
|
|
gap in the schedule.
|
|
- **RAR is not supported**, because it needs native code this app does not ship — and it says so
|
|
rather than failing with a strange error. 7z can be read but not created.
|
|
- **Extraction does not restore timestamps or permissions**, and archive passwords are not
|
|
supported.
|
|
- **Cancelling happens between entries**, so one very large file finishes before a stop is honoured.
|
|
- **English is the only language so far.** Every string is in `strings.xml`, so a translation is a
|
|
file rather than a refactor.
|
|
- **Android TV is specified but not shipped.** Its acceptance needs a TV device pass this machine
|
|
cannot provide, and a half-tested TV build reviews worse than none.
|
|
- **A library is not restored across process death.** Images or Recent returns to the root screen
|
|
after Android kills the process, because a library has no path to persist.
|
|
|
|
#### Privacy, in one paragraph
|
|
|
|
The app declares no `INTERNET` permission, contains no advertising or analytics SDK, and has no
|
|
account or sign-in. It keeps three things on the device — an index of files for search, an index of
|
|
staged deletes for the trash, and the list of starred folders — and none of them leaves it. The
|
|
permission set and why "All files access" is the one sensitive declaration are in the
|
|
[store listing](STORE_LISTING.md); the policy text is [PRIVACY.md](../PRIVACY.md).
|
|
|
|
#### Price
|
|
|
|
**€4.49**, with a **€2.29 launch price for the first 14 days**. One purchase, every feature; no
|
|
subscription and nothing to buy inside the app. There is no Billing client in the build — the price
|
|
lives on the listing — which is part of how "nothing leaves the device" stays true of the shipped
|
|
artefact rather than only of the source.
|
|
|
|
#### What comes next
|
|
|
|
Android TV is specified and waits for a device; the post-1.0 queue and the deliberate deferrals are
|
|
in [ROADMAP](ROADMAP.md). What will not change is the permission set: features arrive without a new
|
|
permission, or they do not arrive.
|