Zipline (Native Rewrite) banner

Zipline (Native Rewrite)

29 devlogs
169h 10m 51s

Updated Project: Rewritten from react-native to Kotlin
Zipline is an Android app made to manage your self-hosted Zipline instance (a service which acts as a file uploader (upload files to share them as URLs wit…

Updated Project: Rewritten from react-native to Kotlin
Zipline is an Android app made to manage your self-hosted Zipline instance (a service which acts as a file uploader (upload files to share them as URLs with options such as max views, deletion date etc.) and as a URL shortener (with similar options to files)) since often web UIs aren’t the best to use on mobile

(This is the second Android app I’ve ever made in Kotlin)

This project uses AI

GitHub Copilot for code completition
Copilot helped me making the background upload notification service and the code that uses it (just the “download*”/“upload*”/“export*” functions in “network/requests” (6 functions) )

Demo Repository

Loading README...

Stef

Fixed the app crashing whenever the user opened the export user settings (because of a scrollable item inside another scrollable item causing a infinite scroll)
Added changelog in the repo (for fdroid)
Updated the site to include a youtube video showcasing the whole app

Attachment
0
Stef

Fix a crash when trying to move up first website, or move down last website, in the admin > settings > website section
Made all settings scrollable to account for smaller screens
Updated the README to add flavortown info
Fixed some edge cases that caused buttons to overflow:

  • Overflowing “…” button when an invite code was too long
  • Overflowing “hide” and “copy” button when a url code or vanity or file/text url was too long
  • Overflowing “…” button when a folder name was too long
  • Overflowing “X subfolders” text when a folder name was too long
  • Overflowing “open” and “… buttons when a user name was too long
Attachment
0
Stef

Added a button on login that allows the user to register (only displayed when the typed URL has user registration enabled)
Added dividers in the admin features screen

Attachment
Attachment
Attachment
0
Stef

Added a check for internet connection since i noticed the reviewer had broken internet connection (on what it seemed to be waydroid) yet it still displayed the app

Attachment
0
Stef

Fixed open button crashing the app instead of opening the browser
Fixed notifications (Notification) sometimes erroring and not showing up
Fixed default domain select being empty when domains list is empty
Use BuildConfig to get the app version in the settings

Attachment
0
Stef

Updated the site to have “get it on forgejo” button instead of github
added a section for flavortown user and flavortown reviewers
updated the images in the carousel to show the new updated rewrite
use forgejo API instead of github to get version name in the footer

Attachment
Attachment
0
Stef

Fixed pager text input not being full size on devices like tablets

Attachment
Attachment
0
Stef

Added fastlane data for F-Droid (currently opened a merge request for the app, https://gitlab.com/fdroid/fdroiddata/-/merge_requests/36552)
Updated build workflow to java 21 and build tools 36
Fixed copied items not appearing in gboard’s clipboard
Added a default domain select in app settings that will be used as domain when copying any url (idk why in the video android decided not to paste last one)
Added client data in the login for the sessions in the web UI (can be anonymized in the login form to hide the device model and user agent and use a default one instead)
Fixed create URL screen not showing a URL for the newly created URL
Added .debug/-debug/ (Debug) to app ID, version and name
Created sessions setting just to then find out that i can’t fetch sessions with a token and so removed it)

Attachment
0
Stef

Added 2 widgets:

  • Recent Files (configurable opacity & file count up to 30)
  • Server Stats (configurable opacity)
    Removed unused imports
0
Stef

Finished moving screens to ViewModel, moved:

  • Admin settings
  • Admin users
  • Admin Invites
    Moved tables and notifications from function(content = { ... }) to function() { ... }
    Fixed admin settings not deleting the value if the input was empty as it was not sending null values to the server, now it does
    Admin settings that are in the tampered list are now disabled in the app too
    Moved most variables from remember {} to rememberSaveable to they can survive configuration changes such as screen rotation

in the image “Delete Files Interval” is disabled because it’s tampered

Attachment
0
Stef

move to ViewModel these screens:

  • admin actions
  • folders
  • urls
  • metrics
  • login
  • home screens
    (i think i didn’t forget any?)

fixed ColorPicker not calling onColorChange when pressing automatic pick button in tags
fixed double %% in metrics
fixed commit SHA being full length in VersionDisplay instead of only taking 7 characters

Attachment
0
Stef

Moved the internal app storage keys (like server url, token, biometric auth status etc.) to constants so i’m sure i never typo them
Fixed the “Remove Avatar” button not working (created its own HTTP request for it cause in updateCurrentuser the API would complain of username and password being null when updating the avatar
Fixed the crash when you save the “Viewing Files” user settings (because the .toString() output was different from the enum actual name so .valueOf would error
In the Notification component moved the duration property above content so i can do Notification.show(...) { content } (which is cleaner and more readable) instead of doing Notification.show([...], content)
Started moving the app’s screen from normal remember {} to ViewModels (currently done URLs, upload file, upload text and user settings)

(idk what to put as attachment since it’s mostly internal stuff so i’ll put images of the success messages of the buttons that would previously error or crash)

Attachment
Attachment
Attachment
0
Stef

Added a check for the server version on login and app open (in the loading screen)
The app now remembers the compact state of each page instead of always defaulting to large mode
Fixed VersionDisplay not correctly displaying the latest commit data (i had put a != instead of == skull_cry

Attachment
Attachment
Attachment
0
Stef

Created folders screen
Added a “no data available” message to all pages that have variable options such as invites, users, files, folders etc.
Created the endpoints to edit folders
Added a close button to the PromptPopup
Created a util isChildOf that returns true if the given folder has the given parentId as one of its parents or grandparents, used to make sure the selected folder is not a child of the one you’re deleting or moving
Fixed MoreActionsButton not correctly disabling the options in the dropdown menu

0
Stef

Created 2 share intent for upload files or shortening files

  • Normal: opens the app to allow customization such as deletion date, max views etc.
  • Quick: uploads with all the default options without ever opening the app and copies the URLs to the clipboard
    Fixed LargeFileDisplay not closing the delete file popup when pressing the delete button
    Fixed LargeFileDisplay not opening any other file on home page (when clicking them from the recent files list) after the deletion of another file (this should apply to files screen too)
    Added a popup to prompt for notification (only if they’re not already granted) in the login screen
    Removed unused imports
0
Stef

Migrate from Toast.makeText().show() to Notification.show()
Migrated from Log.d()/Log.e() to Logger.debug()/Logger.error() (a custom class that automatically removes logcat logging in release builds)
Updated manifest file to use dataSync fg service type / DATA_SYNC permission (as it’s intended for upload/downloads) instead of mediaProcessing / MEDIA_PROCESSING which is intended for image/video editing
Added max file size to file preview (otherwise large files would cause an out of memory error and crash the app
Updated Notification component to allow a custom composable as content instead of a normal strings

Attachment
0
Stef

Added a check to see if the device has enough space for the file or export before it starts downloading (to avoid it erroring after it downloaded many GB of data)
Updated links color, should be more readable on the dark bg hopefully
Created a custom Logger class (still unused yet)
Fixed GetServerVersionResponse values to match actual API return values
Fixed login failing to fetch data (like public/web settings & user avatar)
Created user settings screen

0
Stef

Split the admin settings into multiple categories (chosen via a select menu) so they do not render all at once and thus don’t make the app lag when they load

0
Stef

Created admin invites screen
Created admin users screen
Created admin actions screen
Started making admin settings screen
Updated ColorPicker component to actually change the color on user input (when typing the HEX color manually)
updated server settings error response model since it’s different from all other HTTP endpoints’ error response
Added invite related HTTP requests
Added README.md
Made a custom Notification component that will replace the default android Toast

(yeah, i’m tryna fix the sidebar lagging when opening the settings)

1

Comments

Stef
Stef about 1 month ago

also damn, that devlog time was precise asf

Stef

Created admin users page (kinda just copied and pasted URLs page and modified it to apply for users)
Fixed some HTTP requests not working correctly
Ggeneralized even more the DeletePromptPopup component
Prompt for password if the file requires it instead of showing error 403
Created AvatarInput component for the user to upload their avatar of (if they’re an admin) update other people’s avatar

0
Stef

Updated ApiClient to optionally also send null values (defaults to omit)
Added a toast success message on all copy buttons
Created the URLs page
Generalized the DeleteFilePromptPopup component and renamed to DeletePromptPopup
Created a util to generate QR codes

0
Stef

Changed the condition for the skeleton loading in FilePreview
Fixed password login not working (i had put a check for if the token was in storage… on the function that fetches the token using username & password… 💀)
Fixed login sometimes getting stuck on an endless loading (related to prev line)
Changed Switch description layout
Added a popup for uploaded files and all the upload headers set by the user via selects, text inputs or switches
Created the UploadTextScreen (pretty much similar to upload file just with a text input)
Added handling of camera

0
Stef

Updated some HTTP requests
Updated download path fetching
Added description to Select & TextInput
Finished files screen with tags & incomplete/pending files
Started doing upload files page
Created a ColorPicker compose

0
Stef

FilePreview component now show a placeholder with loading message instead of skeleton loading
Created about 80/90% of files screen (would’ve finished it but it’s 1AM and i got school at 8AM💀)
Updated how Table component works to make it more customizable (like make it sortable, searchable, clickable)
Added KeyboardActions to TextInput component so i can handle physical keyboard enter press
Created a paging system component for the files page 8will be used for other pages too like URLs
Created a HeaderButton component that will be used in all pages that have any button on top on the Zipline web UI

0
Stef

Finished the LargeFileDisplay component
Created the “Metrics” Screen
Updated the skeleton modifier to add optional height/width
disabled navigation to the same route as current in the sidebar (it just closes the sidebar without navigating)
Added keyboard options to the TextInput component (so i can use number only keyboard)
Fixed splash screen color to match icon color

(the video might look worse since i had to compress it from 105 MB to < 50 MB)

0
Stef

Added app icon
Created login screen
FilePreview now tries to generate thumbnails from the video’s first frames
Recent files on home screen are now clickable and open largeFilePreview
Made sidebar scrollable
Created LargeFileDisplay (some buttons still unfinished and download isn’t really polished yet, in the future it won’t always ask for the save folder but only first time), Select and Tag components
Fix folder delete/remove file from folder HTTP schema (@DELETE doesn’t allow having a body so i opted for @HTTP)
Fix Popup height not correctly converting PX to DP
renamed removeFileToFolder to removeFileFromFolder (i think i copy pasted addFileToFolder and didn’t rename the function correctly 💀)

0
Stef

Fixed getAvatar request erroring cuz trying to parse as JSON a base64 image string
Changed File password from PasswordState to Boolean
Added the user avatar to the Header component as a Button that opens settings
Created the app’s home screen
Created VideoPlayer, Table and FilePreview components
Added a scrollbar to some scrollable views

0
Stef

Added light & dark theme
Added biometric auth screen and loading screen
Added Button, TextInput & Switch and Sidebar (mostly copied copied from my Hackatime app and slightly modified)
Updated some API responses

Attachment
Attachment
Attachment
0
Stef

Created all the typedefs for the Zipline API responses, request bodies, queries etc.

I haven’t made any UI on the Kotlin version yet so for now here’s an image of the react native app just to have an idea of how the login screen will look (i didn’t know what else to put since code pics aren’t allowed)

Attachment
0