|
57886
|
GottchX by @sterbolt | Stardance
|
sterbolt
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: GottchX by @sterbolt | Stardance
|
1793461726.376262
|
1794066526.376262
|
|
67087
|
My awesome macropad! by @stepkatech | Stardance
|
stepkatech
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @stepkatech | Stard Title: My awesome macropad! by @stepkatech | Stardance...
|
1793728230.3827953
|
1794333030.3827953
|
|
34014
|
Personal Website by @stephfrd | Stardance
|
stephfrd
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Personal Website by @stephfrd | Stardance
|
1793443900.0795636
|
1794048700.0795636
|
|
46009
|
SARVIS AI by @stephenkam | Stardance
|
stephenkam
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: SARVIS AI by @stephenkam | Stardance
|
1793364828.9991243
|
1793969628.9991243
|
|
5454
|
Macro pad! by @stephenfromcolorado | Stardance
|
stephenfromcolorado
|
0
|
0.29
|
0
|
[]
|
[{"post_id": 1107, "ts": "2026 [{"post_id": 1107, "ts": "2026-06-02T22:45:16Z", "hours": 0.2878, "text": "I made the pcb for the macro pad ts took like a hour but freeking hacka time is so bad"}]...
|
Title: Macro pad! by @stephenfromcolorado | Starda Title: Macro pad! by @stephenfromcolorado | Stardance
Devlogs:
I made the pcb for the macro pad ts took like a hour but freeking hacka time is so bad...
|
1793404272.8029988
|
1794009072.8029988
|
|
5631
|
Untitled by @stephenfromcolorado | Stardance
|
stephenfromcolorado
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled by @stephenfromcolorado | Stardanc Title: Untitled by @stephenfromcolorado | Stardance...
|
1793260228.5693321
|
1793865028.5693321
|
|
4613
|
Recall.me by @stephenfkutuahnjr | Stardance
|
stephenfkutuahnjr
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Recall.me by @stephenfkutuahnjr | Stardance
|
1793364983.7027962
|
1793969783.7027962
|
|
4624
|
My awesome macropad! by @stephenfkutuahnjr | Stard My awesome macropad! by @stephenfkutuahnjr | Stardance...
|
stephenfkutuahnjr
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @stephenfkutuahnjr Title: My awesome macropad! by @stephenfkutuahnjr | Stardance...
|
1793321598.4687867
|
1793926398.4687867
|
|
5421
|
Untitled project by @stephen_stanchev | Stardance
|
stephen_stanchev
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled project by @stephen_stanchev | Sta Title: Untitled project by @stephen_stanchev | Stardance...
|
1793480079.556409
|
1794084879.556409
|
|
64847
|
My first slack bot! by @stephen_kipsang | Stardanc My first slack bot! by @stephen_kipsang | Stardance...
|
stephen_kipsang
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @stephen_kipsang | S Title: My first slack bot! by @stephen_kipsang | Stardance...
|
1793678148.4502184
|
1794282948.4502184
|
|
64854
|
ASTRA-X Explore beyong earth by @stephen_kipsang | ASTRA-X Explore beyong earth by @stephen_kipsang | Stardance...
|
stephen_kipsang
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: ASTRA-X Explore beyong earth by @stephen_ki Title: ASTRA-X Explore beyong earth by @stephen_kipsang | Stardance...
|
1793678155.9874845
|
1794282955.9874845
|
|
1430
|
My first slack bot! by @stephen | Stardance
|
stephen
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @stephen | Stardance
|
1793537376.761384
|
1794142176.761384
|
|
14922
|
My awesome macropad! by @stephcrazy0621 | Stardanc My awesome macropad! by @stephcrazy0621 | Stardance...
|
stephcrazy0621
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @stephcrazy0621 | S Title: My awesome macropad! by @stephcrazy0621 | Stardance...
|
1793386126.3834908
|
1793990926.3834908
|
|
34952
|
Progress Photo App by @stephanvdberg2009 | Stardan Progress Photo App by @stephanvdberg2009 | Stardance...
|
stephanvdberg2009
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Progress Photo App by @stephanvdberg2009 | Title: Progress Photo App by @stephanvdberg2009 | Stardance...
|
1793472506.4289129
|
1794077306.4289129
|
|
25371
|
Speech Improvement Mobile App by @stephanopcg | St Speech Improvement Mobile App by @stephanopcg | Stardance...
|
stephanopcg
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Speech Improvement Mobile App by @stephanop Title: Speech Improvement Mobile App by @stephanopcg | Stardance...
|
1793501739.5664299
|
1794106539.5664299
|
|
33216
|
My very own WebOS by @stephanieg | Stardance
|
stephanieg
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @stephanieg | Stardanc Title: My very own WebOS by @stephanieg | Stardance...
|
1793501680.602213
|
1794106480.602213
|
|
13104
|
My very own WebOS by @stephaniecrush9 | Stardance
|
stephaniecrush9
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @stephaniecrush9 | Sta Title: My very own WebOS by @stephaniecrush9 | Stardance...
|
1793379323.4602966
|
1793984123.4602966
|
|
41133
|
desktop bot by @sten_penners | Stardance
|
sten_penners
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: desktop bot by @sten_penners | Stardance
|
1793541376.6149106
|
1794146176.6149106
|
|
940
|
Spacetex by @stemdood44 | Stardance
|
stemdood44
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Spacetex by @stemdood44 | Stardance
|
1793537685.1147244
|
1794142485.1147244
|
|
13439
|
My very own WebOS by @stemcalifornia | Stardance
|
stemcalifornia
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @stemcalifornia | Star Title: My very own WebOS by @stemcalifornia | Stardance...
|
1793339884.1220872
|
1793944684.1220872
|
|
34533
|
Untitled project by @stem_club_bayankhongor | Star Untitled project by @stem_club_bayankhongor | Stardance...
|
stem_club_bayankhongor
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled project by @stem_club_bayankhongor Title: Untitled project by @stem_club_bayankhongor | Stardance...
|
1793354136.256291
|
1793958936.256291
|
|
32056
|
Untitled project by @stem_aanya | Stardance
|
stem_aanya
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled project by @stem_aanya | Stardance
|
1793361102.9034743
|
1793965902.9034743
|
|
23
|
SAGE by @stellenium | Stardance
|
stellenium
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: SAGE by @stellenium | Stardance
|
1793818355.3705556
|
1794682355.3705556
|
|
549
|
My first slack bot! by @stellenium | Stardance
|
stellenium
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @stellenium | Starda Title: My first slack bot! by @stellenium | Stardance...
|
1793886560.5004728
|
1794750560.5004728
|
|
4171
|
dialbreak by @stellenium | Stardance
|
stellenium
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: dialbreak by @stellenium | Stardance
|
1793883190.9120066
|
1794747190.9120066
|
|
68681
|
the stupidest website OAT by @stellenium | Stardan the stupidest website OAT by @stellenium | Stardance...
|
stellenium
|
0
|
51.63
|
0
|
[]
|
[{"post_id": 77940, "ts": "202 [{"post_id": 77940, "ts": "2026-10-08T21:10:49Z", "hours": 51.6322, "text": "test devlog"}]...
|
Title: the stupidest website OAT by @stellenium | Title: the stupidest website OAT by @stellenium | Stardance
Devlogs:
test devlog...
|
1793746302.5520966
|
1794351102.5520966
|
|
37090
|
WarioWare Game by @stellehuban113 | Stardance
|
stellehuban113
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: WarioWare Game by @stellehuban113 | Stardan Title: WarioWare Game by @stellehuban113 | Stardance...
|
1793476193.6058843
|
1794080993.6058843
|
|
25739
|
WarioWare Game by @stelle | Stardance
|
stelle
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: WarioWare Game by @stelle | Stardance
|
1793850611.115755
|
1794455411.115755
|
|
64324
|
My first slack bot! by @stellan | Stardance
|
stellan
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @stellan | Stardance
|
1793674185.0649302
|
1794278985.0649302
|
|
64326
|
Python Coding by @stellan | Stardance
|
stellan
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Python Coding by @stellan | Stardance
|
1793674188.0376885
|
1794278988.0376885
|
|
18329
|
NovaDeck by @stellalovebird1124 | Stardance
|
stellalovebird1124
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: NovaDeck by @stellalovebird1124 | Stardance
|
1793825286.0245342
|
1794430086.0245342
|
|
5487
|
My awesome macropad! by @stella | Stardance
|
stella
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @stella | Stardance
|
1793426001.466852
|
1794030801.466852
|
|
36634
|
my hack pad by @steliosvastard | Stardance
|
steliosvastard
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: my hack pad by @steliosvastard | Stardance
|
1793472485.5708127
|
1794077285.5708127
|
|
36644
|
Untitled by @steliosvastard | Stardance
|
steliosvastard
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled by @steliosvastard | Stardance
|
1793883293.759633
|
1794488093.759633
|
|
36645
|
Untitled by @steliosvastard | Stardance
|
steliosvastard
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled by @steliosvastard | Stardance
|
1793242472.704282
|
1793847272.704282
|
|
36646
|
Untitled by @steliosvastard | Stardance
|
steliosvastard
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled by @steliosvastard | Stardance
|
1793397021.7173934
|
1794001821.7173934
|
|
50043
|
i want to make a cybershield and a usb by @stelans i want to make a cybershield and a usb by @stelanshyetienne | Stardance...
|
stelanshyetienne
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: i want to make a cybershield and a usb by @ Title: i want to make a cybershield and a usb by @stelanshyetienne | Stardance...
|
1793318148.3203185
|
1793922948.3203185
|
|
38443
|
My first slack bot! by @steftheunknown | Stardance
|
steftheunknown
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @steftheunknown | St Title: My first slack bot! by @steftheunknown | Stardance...
|
1793386389.2562058
|
1793991189.2562058
|
|
3377
|
My awesome macropad! by @stefq | Stardance
|
stefq
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @stefq | Stardance
|
1793573349.3418322
|
1794178149.3418322
|
|
24137
|
My very own WebOS by @stefq | Stardance
|
stefq
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @stefq | Stardance
|
1793562557.3140645
|
1794167357.3140645
|
|
2171
|
My first slack bot! by @stefmaes01 | Stardance
|
stefmaes01
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @stefmaes01 | Starda Title: My first slack bot! by @stefmaes01 | Stardance...
|
1793839808.9046092
|
1794444608.9046092
|
|
33855
|
My first slack bot! by @stefi | Stardance
|
stefi
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @stefi | Stardance
|
1793494469.7126462
|
1794099269.7126462
|
|
13327
|
Personal Website by @stefgogo11 | Stardance
|
stefgogo11
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Personal Website by @stefgogo11 | Stardance
|
1793260071.729986
|
1793864871.729986
|
|
29
|
Hackatime Stats (Android App) by @stefdp | Stardan Hackatime Stats (Android App) by @stefdp | Stardance...
|
stefdp
|
2
|
14.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-31T07:07:21Z", "hours": 1.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "The main things i did were switching to Hackatime OAuth2 (earlier people were just pasting their API key in a password text input) and added the leaderboard tab. Most challenging part was the OAuth2 since this was my first time implementing OAuth2 in an Android app", "repo": "https://git.stefdp.com/Stef/Hackatime-Android-App", "demo": "https://hackatime.stefdp.com"}, {"ship_num": 2, "ts": "2026-10-15T14:29:01Z", "hours": 13.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "The main things i did were switching to Hackatime OAuth2 (earlier people were just pasting their API key in a password text input) and added the leaderboard tab. Most challenging part was the OAuth2 since this was my first time implementing OAuth2 in an Android app", "repo": "https://git.stefdp.com/Stef/Hackatime-Android-App", "demo": "https://hackatime.stefdp.com"}]...
|
[{"post_id": 85370, "ts": "202 [{"post_id": 85370, "ts": "2026-10-31T07:06:03Z", "hours": 0.875, "text": "I legit forgot what i had done cuz it was 2 months ago but iirc it mainly was Bump the version for the play store release Did some tests with the Leaderboard tho they failed or looked bad so i just shashed them Built the APK and AAB files for the release with my actions runner"}, {"post_id": 58205, "ts": "2026-08-30T15:45:23Z", "hours": 4.1458, "text": "Added the leaderboard screen Took Pager , PullToRefresh and TextInput components from my other apps Added pull to refresh in all screens (goals, home, projects & leaderboard (for leaderboard u gotta do it specifically on the leaderboard, not outside)) Fixed a crash when opening a project git repo Fixed login failing to send the API key to the server because i had put it before actually storing the access token so it would error with “Missing access token” installed a lib to load images form the network (used for the avatars in the leaderboard) Improved the .shimmerable modifier Improved spacing in the settings save buttons between the text and the icon/loading spinner Fixed backend API’s sendApiKey function using wrong tag in logging"}, {"post_id": 57738, "ts": "2026-08-30T00:17:08Z", "hours": 2.3383, "text": "Fixed the missing types so now the app builds Updated all HTTP requests that needed an API key so instead of only fetching it, they also cache it Added a HTTP request to revoke the Hackatime OAuth2 access token which is used on logout Added waterfall padding to the Header component (waterfall padding is a larger horizontal padding for phones that have rounded/curved screen edges) Moved LoginScreen , ProjectsScreen , GoalsScreen and SettingsScreen to viewModel Added a scrollbar in all scrollable screens (took the scrollbar code from my other apps) Added the Notification object (this too took from ym other apps) Added base skeleton for the leaderboard tab (just shows “WIP”) GL to the GOIs, the commits for this devlogs were a mess cuz i made alot of changes at once and then tried to split it in multiple commits to avoid making a huge one 😭 🥀"}, {"post_id": 57662, "ts": "2026-08-29T21:41:13Z", "hours": 6.2825, "text": "Switched login to Hackatime OAuth2 (untested) Moved MainActivity to use a viewModel and update the FCM registering Moved HomeScreen to use a viewModel Added a custom Logger class (taken from my other apps) Entirely rewritten the API endpoints using the new API docs Updated the Firebase token registration handling (untested) Made SecureStorage keys constant Updated some function types Renamed “API Key” to “data” in the share to server switch as now it shares the access token Updated libs and raised target SDK from 36 (Android 16) to 37 (Android 17) Current code can not be currently built as most screens have missing types after the API endpoints rewrite also idk what to put as pic since it’s all code changes and can’t build the app so i’ll put the OAuth2 handling with the net.openid:appauth library"}]...
|
Title: Hackatime Stats (Android App) by @stefdp | Title: Hackatime Stats (Android App) by @stefdp | Stardance
Devlogs:
Switched login to Hackatime OAuth2 (untested) Moved MainActivity to use a viewModel and update the FCM registering Moved HomeScreen to use a viewModel Added a custom Logger class (taken from my other apps) Entirely rewritten the API endpoints using the new API docs Updated the Firebase token registration handling (untested) Made SecureStorage keys constant Updated some function types Renamed “API Key” to “data” in the share to server switch as now it shares the access token Updated libs and raised target SDK from 36 (Android 16) to 37 (Android 17) Current code can not be currently built as most screens have missing types after the API endpoints rewrite also idk what to put as pic since it’s all code changes and can’t build the app so i’ll put the OAuth2 handling with the net.openid:appauth library
Fixed the missing types so now the app builds Updated all HTTP requests that needed an API key so instead of only fetching it, they also cache it Added a HTTP request to revoke the Hackatime OAuth2 access token which is used on logout Added waterfall padding to the Header component (waterfall padding is a larger horizontal padding for phones that have rounded/curved screen edges) Moved LoginScreen , ProjectsScreen , GoalsScreen and SettingsScreen to viewModel Added a scrollbar in all scrollable screens (took the scrollbar code from my other apps) Added the Notification object (this too took from ym other apps) Added base skeleton for the leaderboard tab (just shows “WIP”) GL to the GOIs, the commits for this devlogs were a mess cuz i made alot of changes at once and then tried to split it in multiple commits to avoid making a huge one 😭 🥀
Added the leaderboard screen Took Pager , PullToRefresh and TextInput components from my other apps Added pull to refresh in all screens (goals, home, projects & leaderboard (for leaderboard u gotta do it specifically on the leaderboard, not outside)) Fixed a crash when opening a project git repo Fixed login failing to send the API key to the server because i had put it before actually storing the access token so it would error with “Missing access token” installed a lib to load images form the network (used for the avatars in the leaderboard) Improved the .shimmerable modifier Improved spacing in the settings save buttons between the text and the icon/loading spinner Fixed backend API’s sendApiKey function using wrong tag in logging
I legit forgot what i had done cuz it was 2 months ago but iirc it mainly was Bump the version for the play store release Did some tests with the Leaderboard tho they failed or looked bad so i just shashed them Built the APK and AAB files for the release with my actions runner
Ships:
The main things i did were switching to Hackatime OAuth2 (earlier people were just pasting their API key in a password text input) and added the leaderboard tab. Most challenging part was the OAuth2 since this was my first time implementing OAuth2 in an Android app
The main things i did were switching to Hackatime OAuth2 (earlier people were just pasting their API key in a password text input) and added the leaderboard tab. Most challenging part was the OAuth2 since this was my first time implementing OAuth2 in an Android app...
|
1793818220.7146661
|
1793904620.7146661
|
|
67
|
idk, that's proj ID 67 by @stefdp | Stardance
|
stefdp
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: idk, that's proj ID 67 by @stefdp | Sta Title: idk, that's proj ID 67 by @stefdp | Stardance...
|
1793411253.8325882
|
1794016053.8325882
|
|
87
|
Pterodactyl Panel (Android App) by @stefdp | Stard Pterodactyl Panel (Android App) by @stefdp | Stardance...
|
stefdp
|
1
|
157.29
|
1608
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-08-07T14:34:43Z", "hours": 106.0, "multiplier": 15.23, "payout": 1608, "blessing": "neutral", "text": "For rating & testing the project, please first read all of the text in the release. I made an Android app to manage your self-hosted Pterodactyl Panel instance (Currently only the client side, later I’ll also add the admin side). For who doesn’t know, Pterodactyl Panel is a panel usually used to manage game servers, but it can run anything, each server is just a docker container. The most challenging part was prob downloading files, and it still confuses me tbh because on the Android Studio emulator it works fine, but when if I try it on my actual phone (Samsung A55 5G) it randomly stops after a few seconds and I can’t seem to understand why", "repo": "https://git.stefdp.com/Stef/Pterodactyl-Panel-Android-App", "demo": "https://git.stefdp.com/Stef/Pterodactyl-Panel-Android-App/releases/latest"}]...
|
[{"post_id": 55643, "ts": "202 [{"post_id": 55643, "ts": "2026-08-27T16:32:55Z", "hours": 2.5833, "text": "Added updated checking For F-Droid flavor it doesn’t do anything For APK flavor it checks my git repo For Play Store flavor it uses play store com.google.android.play:app-update library Updated the app site, available at https://ptero.stefdp.com Updated the changelog & app images in the fastlane folder Added an animation when switching between loading states with circular loading"}, {"post_id": 55485, "ts": "2026-08-27T11:17:55Z", "hours": 1.5147, "text": "Added optional biometric authentication so people can lock their app behind phone code or biometric verification (like fingerprint etc.)"}, {"post_id": 54826, "ts": "2026-08-25T23:53:13Z", "hours": 3.245, "text": "Created nests, nest & nest egg screens For nest egg screen, created 3 tabs: Configuration Variables Install Script it was pretty easy and quick to create those cuz they’re read-only as there’s no API endpoint to edit/delete them Added a back handler in the tabbed screens so that back button now goes to the previous tab instead of the entire previous screen In the client servers screen added a switch to see others’ server (admin only) Fixed capitalization in the getNestEgg function ( eggid -> eggId )"}, {"post_id": 54513, "ts": "2026-08-25T15:20:42Z", "hours": 2.9808, "text": "Created users & user screen Updated the AGP (Android Gradle Plugin) Table headers now properly support multi line text (previously if one text was multiline while everything else wasn’t, all the divider would have a gap on the bottom except for the multiline one) In the client server screen, settings tab the UUID is now aligned to the right Improved screen change when deleting a server/node/user/location (instead of navController.popBackStack() (which basically acts as the back button) i specifically navigate to generic screen (eg. “user” -> “users”) and remove current screen from the back history so in the case that there is no screen to back into (eg if the app is opened via a deep link or stuff like that) it will go to the generic tab anyway) Added pull to refresh in the location screen"}, {"post_id": 53949, "ts": "2026-08-24T17:33:07Z", "hours": 1.9753, "text": "Created server manage tab (only reinstall & suspend/unsuspend cuz there seem to be no API endpoint to toggle install status & transfer) Created server delete tab Added 2 new button types, SUCCESS (green) and WARNING (yellow) In the admin server screen now most tabs are hidden whent he server is installing"}, {"post_id": 53378, "ts": "2026-08-23T22:08:42Z", "hours": 1.3206, "text": "Created the admin server databases tab (it only supports resetting the password and deleting the databases because for creating a database i need the hosts IDs, which there seem to be no API endpoint to get them) Added a modifier param to the Container component In the client server screen added a param to directly switch to the databases tab (this is used when the user goes from the admin server screen to the client server screen) Fixed “Missing Server ID” notification when client server is opened with databases tab as first tab"}, {"post_id": 52489, "ts": "2026-08-22T17:05:09Z", "hours": 1.9144, "text": "Created the server startup tab Changed the way Container components are spaced in the Build Configuration tab and create server popup In the create server popup disabled the docker image select when only 1 image is available"}, {"post_id": 52173, "ts": "2026-08-22T08:15:57Z", "hours": 4.4989, "text": "Created server screen with its: About tab Details tab Build Configuration tab Fixed pull to reload, it was updating the refreshIndex variable before the main resource actually refreshed and this caused the tabs not to refresh unless the user pulled to refresh twice CodeText component now uses default text style & font weight instead of pre-defined ones (for some reasons with pre-defined ones, in the ScrollableTabRow component it adds like a margin on the bottom of the blue active indicator) Updated UpdateServerDetailsBody to mark required fields as non-nullable In the server owner select, fixed the selected user disappearing if it was not in the search results In the allocation selects: Made the UI use alias:port when an alias is available, otherwise will default to ip:port Moved the ip:port text to a variable to avoid writing the same thing twice"}, {"post_id": 50274, "ts": "2026-08-19T13:03:15Z", "hours": 2.3186, "text": "Added server creation Added a searchable property in the Select component that adds a text input to filter the options Created a regex to check node & server names"}, {"post_id": 49934, "ts": "2026-08-18T22:04:46Z", "hours": 1.0625, "text": "All *Include enums are now chainable so doing ListNodesQueryInclude.SERVERS + ListServersQueryInclude.USER returns servers.user Also now instead of <enum>.toQueryString(...) (like ListServersQueryInclude.toQueryString(...) ) i do listOf(...).toQueryString() Used the new include enum chaining in 2 places: node servers tab: it now makes way less HTTP requests since the user, nest & egg are directly returned with the server, saving me from making multiple HTTP requests to fetch all users, nests & eggs (which would’ve taken a long time on a large server that for example has thousands of users, since it was fetching at a rate of 50 users per HTTP request, and it being a mobile app, internet might not be fast too) servers screen, now it fetches the egg variable together with the nest instead of having to fetch the egg’s data Moved ApiErrorResponse in a models folder for better organization this is a code only change so ig i’ll show pics of the code"}, {"post_id": 49856, "ts": "2026-08-18T20:07:04Z", "hours": 5.0992, "text": "Created the servers screen (WIP, inputs are untested and creating servers is not implemented yet) Created node servers tab Added pagination to the list nests HTTP request response Removed useless reset of the allocations in the node allocations tab In the created node popup, switched some inputs description from \"quoted\" test to actual inline code blocks CodeText component now uses CharSequence instead of String so it also supports annotated strings Switched main components from Text to CodeText Application server status is now an enum Updated list nests query to include eggs variables too (i just found out i can do this so i’m gonna prob do in in all the other ones in the next devlog too)"}, {"post_id": 48195, "ts": "2026-08-16T14:20:45Z", "hours": 4.3858, "text": "Created the node allocations tab The servers screen now shows the server description when available The 2FA check now considers 2FA as enabled even if the status code is 400 other than checking the error message (ptero got no way of knowing if 2FA is enabled other than that ) Update the TextInput component to allow showing optional suggestions (used in the assign new allocations popup, IP Address input) The Checkbox component now is more transparent when disabled (from 0.5 to 0.2 alpha) Changed how padding works in the Pager component Updated the Table component to add a param to disable lazy loading (for some reason it was laggier) Updated the libs"}, {"post_id": 47489, "ts": "2026-08-15T13:07:23Z", "hours": 2.2333, "text": "Created the node configuration tab Renamed the CodeText component to CodeBlockText and added params to highlight the content with a specific language Created the CodeText component to have both normal text and inline code text (kinda like markdown when you do this )"}, {"post_id": 47046, "ts": "2026-08-14T17:23:43Z", "hours": 1.6747, "text": "Create the settings tab in the node screen Added enabled state to all the inputs & switches in the create node popup Updated the updateNode function’s body & params since some required params were marked as nullable"}, {"post_id": 46843, "ts": "2026-08-14T11:23:01Z", "hours": 2.9253, "text": "Created the node screen & its about tab Moved node specific endpoints to their own ApiService instead of having them in the ApplicationApiService and added 2 endpoints to respectively fetch system data in v1 and v2 Made it so create new node button is disabled until all locations are fetched"}, {"post_id": 45978, "ts": "2026-08-12T20:16:10Z", "hours": 2.9544, "text": "Created the popup to create a node When fetching the node lists, now it also fetches all the locations (needed for a select in the create popup) Added fastlane metadata (will be used for F-Droid in the future) The Popup component now has a scrollbar Updated the scrollbar so now it only shows up when the container has enough contents to be scrollable Added an arrangement property in the Table ’s headers & row cells so that i can center certain things Updated TextInput and Switch components to make their description text color customizable Updated the workflow to automatically push the .aab file to play store after it’s built and made the release (hopefully, i didn’t test it) Fixed create location popup not clearing the inputs upon closing"}, {"post_id": 45461, "ts": "2026-08-11T23:00:38Z", "hours": 0.5592, "text": "Fixed admins not being able to manage servers subusers’ permissions Fixed not being aple to open sub-directories in the file browser Fixed create location popup not closing after creating the location"}, {"post_id": 45335, "ts": "2026-08-11T18:39:18Z", "hours": 1.6944, "text": "Created nodes screen (missing the popup to create a node for now) App name is now dynamically generated in the build.gradle.kts file (so debug build get the (Debug) suffix) Added an HTTP endpoint to check a node status"}, {"post_id": 45109, "ts": "2026-08-11T11:53:58Z", "hours": 0.4881, "text": "Created a CodeText component to display text as code (kinda like this ) and applied it in all the places where I previously just copy pasted same code Creating an API key now copies the key to the clipboard"}, {"post_id": 45061, "ts": "2026-08-11T10:17:04Z", "hours": 5.8633, "text": "Created the locations screen Created the location screen Took and modified to adapt to this app the Table component, originally from my Zipline app Fixed the pull to refresh, when calling onRefresh it didn’t actually set isRefreshing to true so the spinner would immediately disappear instead of swithcing to the spinner state till it finished loading Removed the page property from functions since the page is already stored in the viewModel so it made no sense to retrieve it from the viewModel just to send it to a function in the viewModel Fixed the formatDate function, it was crashing the app on older Android versions (<= 13) because the date time parser couldn’t understand the timezone (it expected a date like 2026-08-08-T15:43:30Z instead of 2026-08-08-T15:43:30+02:00 ) Added a new primary color variant that looks good enough on light bgs Fixed some multi-line TextInput s being marked as singleLine"}, {"post_id": 42647, "ts": "2026-08-07T14:13:23Z", "hours": 0.4458, "text": "Fixed the pull to refresh box having incorrect padding, so the circle was being hidden by the header and by the time it was out, it was already fully pulled and so it would refresh Updated the README also did some tests with downloading but i failed so i just undid them without committing or anything"}, {"post_id": 42285, "ts": "2026-08-06T22:21:15Z", "hours": 2.0292, "text": "Created a website for the app & a privacy policy (that was needed for the play store app), it’s available at https://ptero.stefdp.com Added a prompt to request the notification permission in the login screen and a button in the settings in case you want to enable notification in a second moment Improved the eventDescription variable in the ActivityDisplay component (i didn’t even know that was possible, i found it out cuz i made a _count variable and android studio suggested me to put it directly in the when , lmao) Updated versioning to follow SemVer ( 1.0 -> 1.0.0 )"}, {"post_id": 41895, "ts": "2026-08-06T12:09:27Z", "hours": 3.0606, "text": "in the account settings screen added a tab for the app settings Fixed some activity log event having incorrect names and causing the app to crash Added an action to build the app when the commit is prefixed with [build] or [release] Moved the *Scrollbar modifiers above any padding modifier so they look better Switch ScrollableTabRow to a normal Row instead of LazyRow since it’ll never have enough items to cause any lag Updated the README Removed the admin input in the login screen since it’s currently not available"}, {"post_id": 41497, "ts": "2026-08-05T19:00:04Z", "hours": 1.0289, "text": "In the account settings screen created the activity tab (i think i finished all the client side of the app , now i just gotta finish the small importance TODOs like removing the padding to the scrollbar in most scrollable views & stuff like that) Moved ActivityDisplay in the general components as it’s used in the accoutn activity too Updated ActivityDisplay to include the user agent button when available"}, {"post_id": 41417, "ts": "2026-08-05T16:42:56Z", "hours": 0.65, "text": "In the account settings screen added the SSH Keys tab (basically a almost full copy paste of the API Credentials for the frontend) Fixed capitalization of a variable & function in the api key tab"}, {"post_id": 41037, "ts": "2026-08-04T23:29:22Z", "hours": 2.9483, "text": "In the account settings screen created the API credentials tab Update the server screen so each tabs remembers its own data after switching to another tab (previously it would reset when the user switched to another tab). Also tabs now only fetch data on first render, then they use the previously fetched data instead of re-fetching, unless the user manually refreshes via the “pull to refresh” action (the thing where you swipe from top to down and it shows the refresh circle, idk it’s “professional” name ) Applied same changes as above to the account settings screen Updated the formatDate function to include a param to toggle the year in the date"}, {"post_id": 40669, "ts": "2026-08-04T11:04:30Z", "hours": 5.4211, "text": "Added the account settings screen and its account tab (now missing “API Credentials”, “SSH Keys” and “Activity” tabs, then the app is done ) in the server screen’s files tab file names are now limited to one line and if they overflow, they get cut off and “…” is added Now each warning popup in the server screen has its own icon instead of all using the suspended icon in all places, replaced refreshIndex += 1 with refreshIndex++ The app now no longer shows “Missing Server ID” toast as soon as you open a server Fixed disable 2FA endpoint (i forgot to add /disable at the end and i was wondering why 2FA wasn’t getting disabled even tho the request succeeded (without /disable it acts as enable endpoint)) Fixed get qr code response as it was different from what the API docs listed In the get qr code function added a secondary response to tell that 2FA is already enabled (used to check 2FA status so i know whether to show enable or disable button in the 2FA cuz the user object doesn’t tell me if the user has 2FA on … shitty API fr) Added a simple regex to parse emails (so the change email button is enabled only if this regex passes) Servers screen now uses a normal Column instead of a LazyColumn as lazily loading the server was causing more lag than loading all at once (after all it’s just 10 servers per page) Same as above for the server screen activity tab (jusy 25 logs per page) Fixed the pagination system in servers screen and server screen activity tab (for total amount of pages it was using the total amount of items in the current pages ( .total ) instead of the total number of pages ( .totalPages ), idk how i missed that ) Moved the file picker stuff outside of the LazyColumn & put the permissions in a remember to hopefully try to decrease lag I wanted to make a screen rec but i was too lazy to then go and censor my 2FA secret"}, {"post_id": 39547, "ts": "2026-08-02T15:55:34Z", "hours": 5.2503, "text": "Created the activity tab (finally finished all server tabs :D) along with a function to parse the variables in the logs’ description Improved loading for schedules, backup and databases tabs Fixed JSON text highlighting not highlighting strings inside of arrays Added padding for the Waterfall Cutout (aka screens with rounded edges) in the Header and ScrollableTabRow components In the settings tab added a popup to confirm the reinstallation of the server Added the endpoint to get the server activity (idk how i had skipped that one) and its function to call it Renamed AccountActivity to ActivityLog as it’s used in server activity too Installed a lib to generate avatars thta look like “Boring Avatars” one (cuz boring avatars API is paid ) add .trim() to all user inputs Now tabs refresh only when the server ID changes instead of anything in the server object"}, {"post_id": 39101, "ts": "2026-08-01T20:10:32Z", "hours": 4.3317, "text": "Create a custom PullToRefreshBox component that just uses Material3 PullToRefreshBox under the hood, i just made a component so i can easily style it as it’s in 1 single place Added the pull to refresh gesture to servers list & server details screens Added a warning for when the server is suspended, installing, transferring, restoring from a backup or its node is under maintenance (all warnings for now use same icons, i gotta change that) In the servers list servers now are disable and show a pill when they are suspended, installing, transferring, restoring from a backup or their node is under maintenance (basically when the warning is displayed, the server is also disabled aka you can’t access its data like console, files etc.) The app now properly handles padding for devices that have a “waterfall inset” (aka those kind of phones with curved screen at the edge) The top bar in the server list now properly shows a loading state instead of just disappearing and appearing when the user permissions are fetched Created a function hasPermission to check if an user has a certain permission instead of repeating the same code like 20 times Moved StartupContainer to a more general Container Moved ServerStatus enum to Server.Status Removed navController from all tabs as it was unused"}, {"post_id": 38795, "ts": "2026-08-01T11:14:01Z", "hours": 2.0736, "text": "Created the startup tab Made startup variable description nullable as it’s an optional property"}, {"post_id": 38468, "ts": "2026-07-31T21:10:19Z", "hours": 0.7469, "text": "Network tab now just disables all the buttons when loading instead of switching to skeleton loading for any small change like updating an allocation’s notes Doubled hamburger menu icon left padding to match the avatar padding on the right Doubled the gaps between the cards in the backups & network tabs Halved the gaps between the cards in the schedules tab I also tried to make the TextInput label not squared for a while but failed 😭 , for some reasons even if i clip my highest component to rounded corners, it still has the squared bg in the back"}, {"post_id": 38370, "ts": "2026-07-31T18:28:20Z", "hours": 1.9514, "text": "Added the network tab to manage server allocations Added a “Tertiary” button type (just cuz secondary was almost invisible on the allocation bg 🥀) Fixed allocation endpoints using String instead of Long Moved backup popups outside of the padded Column Updated my github username in the readme"}, {"post_id": 36009, "ts": "2026-07-27T20:28:50Z", "hours": 0.4436, "text": "After i tested more the additions of the last devlog i found some issues so here i fixed them Fixed backups downloading as .gz instead of .tar.gz Fixed “Create Backup” not showing up when the current backup count was 0 (making it impossible to create backups at all) Disabled inputs in the restore & create popups when respectively restoring and creating Removed the enabled param in the BackupDisplay as it was basically useless"}, {"post_id": 35992, "ts": "2026-07-27T19:54:26Z", "hours": 4.4839, "text": "Finished the users tab Made the backups tab Made all popup’s horizontal padding equal When editing or creating a new subuser, the permissins that the current user doesn’t have are disabled in the permissions list Disabled the “Create Database” button when at the limit Renamed File to FileDisplay for consistency with other components Fixed edit & create user body still using String instead of ServerSubuser.Permission Fixed the deleteServerBackup function which was marked as GET instead of DELETE Made the truncate param required in the restoreServerBackup function as it’s required in the API"}, {"post_id": 34673, "ts": "2026-07-25T16:12:15Z", "hours": 5.4628, "text": "Started making the users tab but it’s really WIP, none of the buttons except create new user works) Handled subuser permissions for all current tabs Added a LabeledCheckbox component Removed some function params that were pointless to have Installed the Gravatar SDK for the subusers’ avatar I legit think Android Studio is ragebaiting me, as soon as i start the rec the app starts to lag, when i stop the rec it’s fine"}, {"post_id": 34147, "ts": "2026-07-24T17:24:53Z", "hours": 3.77, "text": "Finished handling buttons in the schedules tab & created all the popups for schedule & tasks management In all screens & tab now all the inputs, switches, selects etc. are disabled when loading or making a HTTP request (like delete schedule, update file name etc.) Added a function to convert ISO date strings in human-readable strings Added a missing endpoint to execute a schedule Added a missing only_when_online property in the ServerSchedule data class Fixed schedule & tasks endpoint types (was using String instead of Long for the IDs) Fixed ScrollableTabRow not using all the horizontal space when in landscape mode"}, {"post_id": 33800, "ts": "2026-07-24T00:56:20Z", "hours": 2.5242, "text": "Finished the UI side of the schedule details popup (still WIP for backend like button handling) Moved each popup into its own folder & file to avoid having many long Popup calls at the top of screen/tab files Changed task action from a normal screen to an enum Took the formatDate function from my Zipline app"}, {"post_id": 33067, "ts": "2026-07-22T17:17:14Z", "hours": 4.2242, "text": "Created the schedules tab for the server screen (still WIP, for now only works for displaying & creating schedules, gotta add edit, deletion and task management) Moved each tab to its own ViewModel for better ordering instead of putting everything is a generic one Improved code layout by using return s in some places instead of many if else blocks Fixed ScrollableTabRow component improperly placing icons when there was no text Moved ‘linked’ data class es inside each other so i can do Server.Attributes.Limits instead of having a class with a long name like ApplicationServerAttributesLimits"}, {"post_id": 32681, "ts": "2026-07-22T00:08:40Z", "hours": 5.6317, "text": "Updated the file edit screen to use VSCode’s Dark+ theme colors for highlighting and added Java and CASM/Crawssembly by @The_Craw Added the databases tab with handling for creation, deletion and rotation of the password Fixed rotateServerDatabasePassword and deleteServerDatabase , they were using the wrong endpoint ( /server instead of /servers ) Made each tab independently scrollable instead of making the parent component scrollable Took the IconButton component from my Zipline app and slightly modified it (the MoreActionsButton component now uses that) Changed the Notification object component’s background color"}, {"post_id": 31859, "ts": "2026-07-20T16:06:12Z", "hours": 2.1247, "text": "FInished file handling (handled edit & save files & create new file) Added file highlighting for .env files Fixed writeServerFile having a wrong Content-Type (it had application/json instead of text/plain since the input is a raw string) Fixed HTML syntax highlighting, it wasn’t highlighting the > part of the tag"}, {"post_id": 31721, "ts": "2026-07-20T10:47:03Z", "hours": 2.645, "text": "Added a screen for code editing with simple syntax highlighting (via a newly installed library) and a warning if you try to leave without saving (that’s still WIP, saving isn’t implemented yet and neither reading the content of the selected file) Updated the TextInput component to have a fontFamily property so that in the core editor i can set the text to be monospace On the login screen i disabled the application api key input till the admin side is actually done"}, {"post_id": 31407, "ts": "2026-07-19T19:00:46Z", "hours": 4.4347, "text": "(Sorry for the slightly laggy video, not sure if it’s cuz it’s via a emulator or cuz i compressed the video from 136 MiB down to 36 MB) In the server screen added the handling for download, upload, delete, copy, create folder, rename/move, change permissions, archive & unarchive Filled the File component’s “more actions” menu (before it was empty) Updated uploadServerFiles to be able to upload multiple files at once Added a function to convert linux string permissions (like drwxr-xr-x ) to int/octal (like 755 ) Added a regex for the linux int/octal permission Took the Popup component and Storage object form my Zipline app Updated the SecureStorage class to add the file download folder variable"}, {"post_id": 30962, "ts": "2026-07-18T23:42:06Z", "hours": 2.1631, "text": "Created the Files tab in the server screen (still WIP, most of the buttons do nothing rn) Created a File component to avoid repeating same code Added a new color surfaceContainer used in notifications Took the “More Actions” component from my Zipline app Took the “Checkbox” component from my Zipline app and modified it to be toggleable In server screen disable global scroll on certain tabs as they’d cause the app to crash for infinite scroll moved the WebSocket connection to the Console tab instead of the general server screen, this way it auto reconnects when the user switches back to the console tab (since it disconnects when the user moves to another tab to save resources)"}, {"post_id": 30840, "ts": "2026-07-18T19:40:14Z", "hours": 3.5069, "text": "Added charts to the console tab of the server screen Added a top scrollbar like ptero’s to the server screen and moved the console stuff to its own file for better sorting Created a component for the chart container & top scrollbar to avoid repetition Added AI declaration in the readme cuz i only found out now that it’s required Removed a double new line the Button component"}, {"post_id": 29863, "ts": "2026-07-17T00:51:22Z", "hours": 3.43, "text": "Created the server screen and right now i only made the console section out of all the ones i gotta do (console, files, databases, schedules, users, backups, network, startup, settings & activity) The server screen itself is WIP as it’s missing the buttons to switch between the sections The console tab is also WIP as i haven’t done the line charts for CPU, RAM & Network I/O) (devlogging with this stuff half-made cuz it’s almost 3AM so i gotta sleep ) Took the formatMs function from my zipline app to convert ms to human readable time like “1h 30m 20s” for the server uptime In the WebSocketManager class renamed the setPowerState function to sendPowerSignal as it makes more sense On the console screen i wanted the console to follow its actual colors but only lib i found to do that doesn’t support jetpack compose that well so i had to rely on the XML’s TextView (but in compose thanks to the AndroidView component)"}, {"post_id": 29055, "ts": "2026-07-15T18:23:36Z", "hours": 2.9633, "text": "Fixed websocket not working (apparently it 403’s unless you put the panel URL as Origin header) Added pagination to the servers screen and also made the server load lazily and get unrendered when out of the display Also suspended servers’ names now are grayed out Installed a ANSI parser library to correctly color console output (hopefully it works however they already said it won’t work for outline 😭) Took the scrollbar modifiers from my Zipline app and put a scrollbar in the servers list Created a object to easily access the WebSocketManager from a ViewModel class Currently working on the specific server page, right now it’s empty but i got websocket working, i’ll push it once it’s finished"}, {"post_id": 28568, "ts": "2026-07-14T21:58:36Z", "hours": 3.9736, "text": "Added the UI for the client servers list screen (still gotta finish it tho, just have to add pagination and will only shows 10 servers per page to avoid getting ratelimited as i have to make a separate HTTP request for each server to get their resources usage) Added pterodactyl panel colors to be used in the server status (red, green and yellow) Fixed listServers not working cuz of wrong path (i didn’t know how to tell retrofit to use just the baseUrl , then after it threw an error i googled it and realized i just had to put . ) Updated getServerResources response class, now the server state uses a enum instead of a generic string Updated Server class to better fix some typed and add 1 missing key Added the uploadServerFile HTTP method (i didn’t do i it initially cuz the docs were confusing and i couldn’t understand how to select the upload directory, turns out i was setting the directory query on the request to get the signed url instead of the signed url itself 😭 Improved login process to handle the case when the user logged with just an application api key and not a client one Added application API key validation for the same reason as the login Took shimmerable modifier from my Zipline app to make skeleton loading Added definitions & placeholders for all screens until i make them"}, {"post_id": 28257, "ts": "2026-07-14T12:33:25Z", "hours": 2.8692, "text": "Created Loading and Login Screen After making a HTTP request the app crashed and only then i realized that i didn’t make the HTTP request suspend functions so i fixed it Took the Notification object from my Zipline app, tho i gotta fix it a bit cuz the color is kinda ugly and i still don’t know which one in the palette to use cuz imo none of them fits, maybe i’ll just use a separate color out of the palette for it Updated the TextInput component to add a optional required field which when set to true adds a red * next to the label, might do this with switches too I took some common regex (domain, IPv4, number and decimal) since i might need them later and some of them (domain & IPv4) are also aready used in the login"}, {"post_id": 27777, "ts": "2026-07-13T17:06:27Z", "hours": 2.8914, "text": "Finished creating the methods to call the client API (same as application ones, copy pasted same code and changed method & function vars) (except for the download* ones, i took those from my other app Zipline) I also took the Transfer Service from my Zipline app Updated all the libraries Set target SDK to 37 (Android 17) now i gotta do the frontend part"}, {"post_id": 27272, "ts": "2026-07-12T18:21:50Z", "hours": 0.7419, "text": "Finished creating the methods to call the application API (basically just copy pasted same code and changed the method & the fuction vars) Now i gotta make the same thing for the client API"}, {"post_id": 27163, "ts": "2026-07-12T14:07:41Z", "hours": 1.4042, "text": "Started creating methods to call the API endpoints easily Took the Header component from one of my other apps"}, {"post_id": 26528, "ts": "2026-07-11T12:05:14Z", "hours": 0.8058, "text": "Set up color scheme (right now both light and dark color are the same, idk what colors to use to differ but make it still look like the official app) Added some util modules that i also use in my other apps Created an empty login screen"}, {"post_id": 26500, "ts": "2026-07-11T10:27:23Z", "hours": 0.9733, "text": "I had forgotten to add the client API HTTP endpoint to get the console websocket token & URL so i added it now Added the WebSocket handling (untested) Updated the proguard rules so that HTTP request/response classes are not shrunk or minified by R6"}, {"post_id": 26100, "ts": "2026-07-10T18:05:31Z", "hours": 0.6336, "text": "Finished adding the application API HTTP requests (added application/servers/{serverId}/databases , application/nests and application/nests/{nestId}/eggs ) Also fixed some classes having wrong data cuz i realized that i copy pasted them without actually changing their name in some places 😭 you can see them in the commit here even tho i’m kinda confused cuz in the docs i didn’t see any endpoint to create or manage nests, eggs and database hosts"}, {"post_id": 26051, "ts": "2026-07-10T17:14:07Z", "hours": 2.1628, "text": "Added more application API HTTP requests (all the application/nodes/{nodeId}/allocations , application/locations and application/servers endpoints) you can see them in the commit here"}, {"post_id": 21431, "ts": "2026-07-03T11:41:26Z", "hours": 2.1569, "text": "Added more application API HTTP requests (all the /application/user and /application/nodes endpoints) you can see them in the commit here"}, {"post_id": 7486, "ts": "2026-06-12T14:24:53Z", "hours": 1.1056, "text": "Split the API in 2 types: application and client (as pterodactyl handles those differently with 2 diff api keys) Fixed some wrong or missing types Finished adding the HTTP requests for the client API Started adding the HTTP requests for the application API"}, {"post_id": 7451, "ts": "2026-06-12T12:46:34Z", "hours": 1.6653, "text": "Added more HTTP requests (ngl am too lazy to list them all, just watch them in the commit here )"}, {"post_id": 4342, "ts": "2026-06-07T16:58:23Z", "hours": 4.2092, "text": "Added even more HTTP requests, tho could be not 100% accurate cuz ptero API is shit 😭, the official one is AI generated and has hallucinations…. anyway i added: GET /api/client/account/activity GET /api/client/account/ssh-keys POST /api/client/account/ssh-keys POST /api/client/account/ssh-keys/remove GET /api/client/servers/{identifier} GET /api/client/servers/{identifier}/resources POST /api/client/servers/{identifier}/command POST /api/client/servers/{identifier}/power GET /api/client/servers/{identifier}/databases POST /api/client/servers/{identifier}/databases POST /api/client/server/{serverIdentifier}/databases/{databaseIdentifier)/rotate-password DELETE /api/client/server/{serverIdentifier}/databases/{databaseIdentifier} GET /api/client/servers/{identifier}/files/list GET /api/client/servers/{identifier}/files/contents GET /api/client/servers/{identifier}/files/download POST /api/client/servers/{identifier}/files/write POST /api/client/servers/{identifier}/files/create-folder POST /api/client/servers/{identifier}/files/copy PUT /api/client/servers/{identifier}/files/rename POST /api/client/servers/{identifier}/files/compress POST /api/client/servers/{identifier}/files/decompress POST /api/client/servers/{identifier}/files/delete GET /api/client/servers/{identifier}/files/upload POST /api/client/servers/{identifier}/files/chmod GET /api/client/servers/{identifier}/schedules GET /api/client/servers/{identifier}/schedules/{scheduleIdentifier} POST /api/client/servers/{identifier}/schedules POST /api/client/servers/{identifier}/schedules/{scheduleIdentifier} DELETE /api/client/servers/{identifier}/schedules/{scheduleIdentifier} POST /api/client/servers/{serverIdentifier}/schedules/{scheduleIdentifier}/tasks POST /api/client/servers/{serverIdentifier}/schedules/{scheduleIdentifier}/tasks/{taskIdentifier} DELETE /api/client/servers/{serverIdentifier}/schedules/{scheduleIdentifier}/tasks/{taskIdentifier} Writing all these took alot of time"}, {"post_id": 3759, "ts": "2026-06-06T20:13:46Z", "hours": 1.5667, "text": "Started adding some HTTP requests typedef, still missing alot tho for now i added: GET /api/client GET /api/client/permissions GET /api/client/account GET /api/client/account/two-factor POST /api/client/account/two-factor (enable) POST /api/client/account/two-factor (disable) PUT /api/client/account/email PUT /api/client/account/password GET /api/client/account/api-keys DELETE /api/client/account/api-keys/{identifier} POST /api/client/account/api-keys no frontend yet, i’m doing the backend first"}, {"post_id": 3611, "ts": "2026-06-06T16:44:59Z", "hours": 0.7236, "text": "Just created the app skeleton based on the other 2 apps i’ve already made (with alot of TODOs for now) now working on writing the code for HTTP requests to the pterodactyl API and their response types"}]...
|
Title: Pterodactyl Panel (Android App) by @stefdp Title: Pterodactyl Panel (Android App) by @stefdp | Stardance
Devlogs:
Just created the app skeleton based on the other 2 apps i’ve already made (with alot of TODOs for now) now working on writing the code for HTTP requests to the pterodactyl API and their response types
Started adding some HTTP requests typedef, still missing alot tho for now i added: GET /api/client GET /api/client/permissions GET /api/client/account GET /api/client/account/two-factor POST /api/client/account/two-factor (enable) POST /api/client/account/two-factor (disable) PUT /api/client/account/email PUT /api/client/account/password GET /api/client/account/api-keys DELETE /api/client/account/api-keys/{identifier} POST /api/client/account/api-keys no frontend yet, i’m doing the backend first
Added even more HTTP requests, tho could be not 100% accurate cuz ptero API is shit 😭, the official one is AI generated and has hallucinations…. anyway i added: GET /api/client/account/activity GET /api/client/account/ssh-keys POST /api/client/account/ssh-keys POST /api/client/account/ssh-keys/remove GET /api/client/servers/{identifier} GET /api/client/servers/{identifier}/resources POST /api/client/servers/{identifier}/command POST /api/client/servers/{identifier}/power GET /api/client/servers/{identifier}/databases POST /api/client/servers/{identifier}/databases POST /api/client/server/{serverIdentifier}/databases/{databaseIdentifier)/rotate-password DELETE /api/client/server/{serverIdentifier}/databases/{databaseIdentifier} GET /api/client/servers/{identifier}/files/list GET /api/client/servers/{identifier}/files/contents GET /api/client/servers/{identifier}/files/download POST /api/client/servers/{identifier}/files/write POST /api/client/servers/{identifier}/files/create-folder POST /api/client/servers/{identifier}/files/copy PUT /api/client/servers/{identifier}/files/rename POST /api/client/servers/{identifier}/files/compress POST /api/client/servers/{identifier}/files/decompress POST /api/client/servers/{identifier}/files/delete GET /api/client/servers/{identifier}/files/upload POST /api/client/servers/{identifier}/files/chmod GET /api/client/servers/{identifier}/schedules GET /api/client/servers/{identifier}/schedules/{scheduleIdentifier} POST /api/client/servers/{identifier}/schedules POST /api/client/servers/{identifier}/schedules/{scheduleIdentifier} DELETE /api/client/servers/{identifier}/schedules/{scheduleIdentifier} POST /api/client/servers/{serverIdentifier}/schedules/{scheduleIdentifier}/tasks POST /api/client/servers/{serverIdentifier}/schedules/{scheduleIdentifier}/tasks/{taskIdentifier} DELETE /api/client/servers/{serverIdentifier}/schedules/{scheduleIdentifier}/tasks/{taskIdentifier} Writing all these took alot of time
Added more HTTP requests (ngl am too lazy to list them all, just watch them in the commit here )
Split the API in 2 types: application and client (as pterodactyl handles those differently with 2 diff api keys) Fixed some wrong or missing types Finished adding the HTTP requests for the client API Started adding the HTTP requests for the application API
Added more application API HTTP requests (all the /application/user and /application/nodes endpoints) you can see them in the commit here
Added more application API HTTP requests (all the application/nodes/{nodeId}/allocations , application/locations and application/servers endpoints) you can see them in the commit here
Finished adding the application API HTTP requests (added application/servers/{serverId}/databases , application/nests and application/nests/{nestId}/eggs ) Also fixed some classes having wrong data cuz i realized that i copy pasted them without actually changing their name in some places 😭 you can see them in the commit here even tho i’m kinda confused cuz in the docs i didn’t see any endpoint to create or manage nests, eggs and database hosts
I had forgotten to add the client API HTTP endpoint to get the console websocket token & URL so i added it now Added the WebSocket handling (untested) Updated the proguard rules so that HTTP request/response classes are not shrunk or minified by R6
Set up color scheme (right now both light and dark color are the same, idk what colors to use to differ but make it still look like the official app) Added some util modules that i also use in my other apps Created an empty login screen
Started creating methods to call the API endpoints easily Took the Header component from one of my other apps
Finished creating the methods to call the application API (basically just copy pasted same code and changed the method & the fuction vars) Now i gotta make the same thing for the client API
Finished creating the methods to call the client API (same as application ones, copy pasted same code and changed method & function vars) (except for the download* ones, i took those from my other app Zipline) I also took the Transfer Service from my Zipline app Updated all the libraries Set target SDK to 37 (Android 17) now i gotta do the frontend part
Created Loading and Login Screen After making a HTTP request the app crashed and only then i realized that i didn’t make the HTTP request suspend functions so i fixed it Took the Notification object from my Zipline app, tho i gotta fix it a bit cuz the color is kinda ugly and i still don’t know which one in the palette to use cuz imo none of them fits, maybe i’ll just use a separate color out of the palette for it Updated the TextInput component to add a optional required field which when set to true adds a red * next to the label, might do this with switches too I took some common regex (domain, IPv4, number and decimal) since i might need them later and some of them (domain & IPv4) are also aready used in the login
Added the UI for the client servers list screen (still gotta finish it tho, just have to add pagination and will only shows 10 servers per page to avoid getting ratelimited as i have to make a separate HTTP request for each server to get their resources usage) Added pterodactyl panel colors to be used in the server status (red, green and yellow) Fixed listServers not working cuz of wrong path (i didn’t know how to tell retrofit to use just the baseUrl , then after it threw an error i googled it and realized i just had to put . ) Updated getServerResources response class, now the server state uses a enum instead of a generic string Updated Server class to better fix some typed and add 1 missing key Added the uploadServerFile HTTP method (i didn’t do i it initially cuz the docs were confusing and i couldn’t understand how to select the upload directory, turns out i was setting the directory query on the request to get the signed url instead of the signed url itself 😭 Improved login process to handle the case when the user logged with just an application api key and not a client one Added application API key validation for the same reason as the login Took shimmerable modifier from my Zipline app to make skeleton loading Added definitions & placeholders for all screens until i make them
Fixed websocket not working (apparently it 403’s unless you put the panel URL as Origin header) Added pagination to the servers screen and also made the server load lazily and get unrendered when out of the display Also suspended servers’ names now are grayed out Installed a ANSI parser library to correctly color console output (hopefully it works however they already said it won’t work for outline 😭) Took the scrollbar modifiers from my Zipline app and put a scrollbar in the servers list Created a object to easily access the WebSocketManager from a ViewModel class Currently working on the specific server page, right now it’s empty but i got websocket working, i’ll push it once it’s finished
Created the server screen and right now i only made the console section out of all the ones i gotta do (console, files, databases, schedules, users, backups, network, startup, settings & activity) The server screen itself is WIP as it’s missing the buttons to switch between the sections The console tab is also WIP as i haven’t done the line charts for CPU, RAM & Network I/O) (devlogging with this stuff half-made cuz it’s almost 3AM so i gotta sleep ) Took the formatMs function from my zipline app to convert ms to human readable time like “1h 30m 20s” for the server uptime In the WebSocketManager class renamed the setPowerState function to sendPowerSignal as it makes more sense On the console screen i wanted the console to follow its actual colors but only lib i found to do that doesn’t support jetpack compose that well so i had to rely on the XML’s TextView (but in compose thanks to the AndroidView component)
Added charts to the console tab of the server screen Added a top scrollbar like ptero’s to the server screen and moved the console stuff to its own file for better sorting Created a component for the chart container & top scrollbar to avoid repetition Added AI declaration in the readme cuz i only found out now that it’s required Removed a double new line the Button component
Created the Files tab in the server screen (still WIP, most of the buttons do nothing rn) Created a File component to avoid repeating same code Added a new color surfaceContainer used in notifications Took the “More Actions” component from my Zipline app Took the “Checkbox” component from my Zipline app and modified it to be toggleable In server screen disable global scroll on certain tabs as they’d cause the app to crash for infinite scroll moved the WebSocket connection to the Console tab instead of the general server screen, this way it auto reconnects when the user switches back to the console tab (since it disconnects when the user moves to another tab to save resources)
(Sorry for the slightly laggy video, not sure if it’s cuz it’s via a emulator or cuz i compressed the video from 136 MiB down to 36 MB) In the server screen added the handling for download, upload, delete, copy, create folder, rename/move, change permissions, archive & unarchive Filled the File component’s “more actions” menu (before it was empty) Updated uploadServerFiles to be able to upload multiple files at once Added a function to convert linux string permissions (like drwxr-xr-x ) to int/octal (like 755 ) Added a regex for the linux int/octal permission Took the Popup component and Storage object form my Zipline app Updated the SecureStorage class to add the file download folder variable
Added a screen for code editing with simple syntax highlighting (via a newly installed library) and a warning if you try to leave without saving (that’s still WIP, saving isn’t implemented yet and neither reading the content of the selected file) Updated the TextInput component to have a fontFamily property so that in the core editor i can set the text to be monospace On the login screen i disabled the application api key input till the admin side is actually done
FInished file handling (handled edit & save files & create new file) Added file highlighting for .env files Fixed writeServerFile having a wrong Content-Type (it had application/json instead of text/plain since the input is a raw string) Fixed HTML syntax highlighting, it wasn’t highlighting the > part of the tag
Updated the file edit screen to use VSCode’s Dark+ theme colors for highlighting and added Java and CASM/Crawssembly by @The_Craw Added the databases tab with handling for creation, deletion and rotation of the password Fixed rotateServerDatabasePassword and deleteServerDatabase , they were using the wrong endpoint ( /server instead of /servers ) Made each tab independently scrollable instead of making the parent component scrollable Took the IconButton component from my Zipline app and slightly modified it (the MoreActionsButton component now uses that) Changed the Notification object component’s background color
Created the schedules tab for the server screen (still WIP, for now only works for displaying & creating schedules, gotta add edit, deletion and task management) Moved each tab to its own ViewModel for better ordering instead of putting everything is a generic one Improved code layout by using return s in some places instead of many if else blocks Fixed ScrollableTabRow component improperly placing icons when there was no text Moved ‘linked’ data class es inside each other so i can do Server.Attributes.Limits instead of having a class with a long name like ApplicationServerAttributesLimits
Finished the UI side of the schedule details popup (still WIP for backend like button handling) Moved each popup into its own folder & file to avoid having many long Popup calls at the top of screen/tab files Changed task action from a normal screen to an enum Took the formatDate function from my Zipline app
Finished handling buttons in the schedules tab & created all the popups for schedule & tasks management In all screens & tab now all the inputs, switches, selects etc. are disabled when loading or making a HTTP request (like delete schedule, update file name etc.) Added a function to convert ISO date strings in human-readable strings Added a missing endpoint to execute a schedule Added a missing only_when_online property in the ServerSchedule data class Fixed schedule & tasks endpoint types (was using String instead of Long for the IDs) Fixed ScrollableTabRow not using all the horizontal space when in landscape mode
Started making the users tab but it’s really WIP, none of the buttons except create new user works) Handled subuser permissions for all current tabs Added a LabeledCheckbox component Removed some function params that were pointless to have Installed the Gravatar SDK for the subusers’ avatar I legit think Android Studio is ragebaiting me, as soon as i start the rec the app starts to lag, when i stop the rec it’s fine
Finished the users tab Made the backups tab Made all popup’s horizontal padding equal When editing or creating a new subuser, the permissins that the current user doesn’t have are disabled in the permissions list Disabled the “Create Database” button when at the limit Renamed File to FileDisplay for consistency with other components Fixed edit & create user body still using String instead of ServerSubuser.Permission Fixed the deleteServerBackup function which was marked as GET instead of DELETE Made the truncate param required in the restoreServerBackup function as it’s required in the API
After i tested more the additions of the last devlog i found some issues so here i fixed them Fixed backups downloading as .gz instead of .tar.gz Fixed “Create Backup” not showing up when the current backup count was 0 (making it impossible to create backups at all) Disabled inputs in the restore & create popups when respectively restoring and creating Removed the enabled param in the BackupDisplay as it was basically useless
Added the network tab to manage server allocations Added a “Tertiary” button type (just cuz secondary was almost invisible on the allocation bg 🥀) Fixed allocation endpoints using String instead of Long Moved backup popups outside of the padded Column Updated my github username in the readme
Network tab now just disables all the buttons when loading instead of switching to skeleton loading for any small change like updating an allocation’s notes Doubled hamburger menu icon left padding to match the avatar padding on the right Doubled the gaps between the cards in the backups & network tabs Halved the gaps between the cards in the schedules tab I also tried to make the TextInput label not squared for a while but failed 😭 , for some reasons even if i clip my highest component to rounded corners, it still has the squared bg in the back
Created the startup tab Made startup variable description nullable as it’s an optional property
Create a custom PullToRefreshBox component that just uses Material3 PullToRefreshBox under the hood, i just made a component so i can easily style it as it’s in 1 single place Added the pull to refresh gesture to servers list & server details screens Added a warning for when the server is suspended, installing, transferring, restoring from a backup or its node is under maintenance (all warnings for now use same icons, i gotta change that) In the servers list servers now are disable and show a pill when they are suspended, installing, transferring, restoring from a backup or their node is under maintenance (basically when the warning is displayed, the server is also disabled aka you can’t access its data like console, files etc.) The app now properly handles padding for devices that have a “waterfall inset” (aka those kind of phones with curved screen at the edge) The top bar in the server list now properly shows a loading state instead of just disappearing and appearing when the user permissions are fetched Created a function hasPermission to check if an user has a certain permission instead of repeating the same code like 20 times Moved StartupContainer to a more general Container Moved ServerStatus enum to Server.Status Removed navController from all tabs as it was unused
Created the activity tab (finally finished all server tabs :D) along with a function to parse the variables in the logs’ description Improved loading for schedules, backup and databases tabs Fixed JSON text highlighting not highlighting strings inside of arrays Added padding for the Waterfall Cutout (aka screens with rounded edges) in the Header and ScrollableTabRow components In the settings tab added a popup to confirm the reinstallation of the server Added the endpoint to get the server activity (idk how i had skipped that one) and its function to call it Renamed AccountActivity to ActivityLog as it’s used in server activity too Installed a lib to generate avatars thta look like “Boring Avatars” one (cuz boring avatars API is paid ) add .trim() to all user inputs Now tabs refresh only when the server ID changes instead of anything in the server object
Added the account settings screen and its account tab (now missing “API Credentials”, “SSH Keys” and “Activity” tabs, then the app is done ) in the server screen’s files tab file names are now limited to one line and if they overflow, they get cut off and “…” is added Now each warning popup in the server screen has its own icon instead of all using the suspended icon in all places, replaced refreshIndex += 1 with refreshIndex++ The app now no longer shows “Missing Server ID” toast as soon as you open a server Fixed disable 2FA endpoint (i forgot to add /disable at the end and i was wondering why 2FA wasn’t getting disabled even tho the request succeeded (without /disable it acts as enable endpoint)) Fixed get qr code response as it was different from what the API docs listed In the get qr code function added a secondary response to tell that 2FA is already enabled (used to check 2FA status so i know whether to show enable or disable button in the 2FA cuz the user object doesn’t tell me if the user has 2FA on … shitty API fr) Added a simple regex to parse emails (so the change email button is enabled only if this regex passes) Servers screen now uses a normal Column instead of a LazyColumn as lazily loading the server was causing more lag than loading all at once (after all it’s just 10 servers per page) Same as above for the server screen activity tab (jusy 25 logs per page) Fixed the pagination system in servers screen and server screen activity tab (for total amount of pages it was using the total amount of items in the current pages ( .total ) instead of the total number of pages ( .totalPages ), idk how i missed that ) Moved the file picker stuff outside of the LazyColumn & put the permissions in a remember to hopefully try to decrease lag I wanted to make a screen rec but i was too lazy to then go and censor my 2FA secret
In the account settings screen created the API credentials tab Update the server screen so each tabs remembers its own data after switching to another tab (previously it would reset when the user switched to another tab). Also tabs now only fetch data on first render, then they use the previously fetched data instead of re-fetching, unless the user manually refreshes via the “pull to refresh” action (the thing where you swipe from top to down and it shows the refresh circle, idk it’s “professional” name ) Applied same changes as above to the account settings screen Updated the formatDate function to include a param to toggle the year in the date
In the account settings screen added the SSH Keys tab (basically a almost full copy paste of the API Credentials for the frontend) Fixed capitalization of a variable & function in the api key tab
In the account settings screen created the activity tab (i think i finished all the client side of the app , now i just gotta finish the small importance TODOs like removing the padding to the scrollbar in most scrollable views & stuff like that) Moved ActivityDisplay in the general components as it’s used in the accoutn activity too Updated ActivityDisplay to include the user agent button when available
in the account settings screen added a tab for the app settings Fixed some activity log event having incorrect names and causing the app to crash Added an action to build the app when the commit is prefixed with [build] or [release] Moved the *Scrollbar modifiers above any padding modifier so they look better Switch ScrollableTabRow to a normal Row instead of LazyRow since it’ll never have enough items to cause any lag Updated the README Removed the admin input in the login screen since it’s currently not available
Created a website for the app & a privacy policy (that was needed for the play store app), it’s available at https://ptero.stefdp.com Added a prompt to request the notification permission in the login screen and a button in the settings in case you want to enable notification in a second moment Improved the eventDescription variable in the ActivityDisplay component (i didn’t even know that was possible, i found it out cuz i made a _count variable and android studio suggested me to put it directly in the when , lmao) Updated versioning to follow SemVer ( 1.0 -> 1.0.0 )
Fixed the pull to refresh box having incorrect padding, so the circle was being hidden by the header and by the time it was out, it was already fully pulled and so it would refresh Updated the README also did some tests with downloading but i failed so i just undid them without committing or anything
Created the locations screen Created the location screen Took and modified to adapt to this app the Table component, originally from my Zipline app Fixed the pull to refresh, when calling onRefresh it didn’t actually set isRefreshing to true so the spinner would immediately disappear instead of swithcing to the spinner state till it finished loading Removed the page property from functions since the page is already stored in the viewModel so it made no sense to retrieve it from the viewModel just to send it to a function in the viewModel Fixed the formatDate function, it was crashing the app on older Android versions (<= 13) because the date time parser couldn’t understand the timezone (it expected a date like 2026-08-08-T15:43:30Z instead of 2026-08-08-T15:43:30+02:00 ) Added a new primary color variant that looks good enough on light bgs Fixed some multi-line TextInput s being marked as singleLine
Created a CodeText component to display text as code (kinda like this ) and applied it in all the places where I previously just copy pasted same code Creating an API key now copies the key to the clipboard
Created nodes screen (missing the popup to create a node for now) App name is now dynamically generated in the build.gradle.kts file (so debug build get the (Debug) suffix) Added an HTTP endpoint to check a node status
Fixed admins not being able to manage servers subusers’ permissions Fixed not being aple to open sub-directories in the file browser Fixed create location popup not closing after creating the location
Created the popup to create a node When fetching the node lists, now it also fetches all the locations (needed for a select in the create popup) Added fastlane metadata (will be used for F-Droid in the future) The Popup component now has a scrollbar Updated the scrollbar so now it only shows up when the container has enough contents to be scrollable Added an arrangement property in the Table ’s headers & row cells so that i can center certain things Updated TextInput and Switch components to make their description text color customizable Updated the workflow to automatically push the .aab file to play store after it’s built and made the release (hopefully, i didn’t test it) Fixed create location popup not clearing the inputs upon closing
Created the node screen & its about tab Moved node specific endpoints to their own ApiService instead of having them in the ApplicationApiService and added 2 endpoints to respectively fetch system data in v1 and v2 Made it so create new node button is disabled until all locations are fetched
Create the settings tab in the node screen Added enabled state to all the inputs & switches in the create node popup Updated the updateNode function’s body & params since some required params were marked as nullable
Created the node configuration tab Renamed the CodeText component to CodeBlockText and added params to highlight the content with a specific language Created the CodeText component to have both normal text and inline code text (kinda like markdown when you do this )
Created the node allocations tab The servers screen now shows the server description when available The 2FA check now considers 2FA as enabled even if the status code is 400 other than checking the error message (ptero got no way of knowing if 2FA is enabled other than that ) Update the TextInput component to allow showing optional suggestions (used in the assign new allocations popup, IP Address input) The Checkbox component now is more transparent when disabled (from 0.5 to 0.2 alpha) Changed how padding works in the Pager component Updated the Table component to add a param to disable lazy loading (for some reason it was laggier) Updated the libs
Created the servers screen (WIP, inputs are untested and creating servers is not implemented yet) Created node servers tab Added pagination to the list nests HTTP request response Removed useless reset of the allocations in the node allocations tab In the created node popup, switched some inputs description from "quoted" test to actual inline code blocks CodeText component now uses CharSequence instead of String so it also supports annotated strings Switched main components from Text to CodeText Application server status is now an enum Updated list nests query to include eggs variables too (i just found out i can do this so i’m gonna prob do in in all the other ones in the next devlog too)
All *Include enums are now chainable so doing ListNodesQueryInclude.SERVERS + ListServersQueryInclude.USER returns servers.user Also now instead of <enum>.toQueryString(...) (like ListServersQueryInclude.toQueryString(...) ) i do listOf(...).toQueryString() Used the new include enum chaining in 2 places: node servers tab: it now makes way less HTTP requests since the user, nest & egg are directly returned with the server, saving me from making multiple HTTP requests to fetch all users, nests & eggs (which would’ve taken a long time on a large server that for example has thousands of users, since it was fetching at a rate of 50 users per HTTP request, and it being a mobile app, internet might not be fast too) servers screen, now it fetches the egg variable together with the nest instead of having to fetch the egg’s data Moved ApiErrorResponse in a models folder for better organization this is a code only change so ig i’ll show pics of the code
Added server creation Added a searchable property in the Select component that adds a text input to filter the options Created a regex to check node & server names
Created server screen with its: About tab Details tab Build Configuration tab Fixed pull to reload, it was updating the refreshIndex variable before the main resource actually refreshed and this caused the tabs not to refresh unless the user pulled to refresh twice CodeText component now uses default text style & font weight instead of pre-defined ones (for some reasons with pre-defined ones, in the ScrollableTabRow component it adds like a margin on the bottom of the blue active indicator) Updated UpdateServerDetailsBody to mark required fields as non-nullable In the server owner select, fixed the selected user disappearing if it was not in the search results In the allocation selects: Made the UI use alias:port when an alias is available, otherwise will default to ip:port Moved the ip:port text to a variable to avoid writing the same thing twice
Created the server startup tab Changed the way Container components are spaced in the Build Configuration tab and create server popup In the create server popup disabled the docker image select when only 1 image is available
Created the admin server databases tab (it only supports resetting the password and deleting the databases because for creating a database i need the hosts IDs, which there seem to be no API endpoint to get them) Added a modifier param to the Container component In the client server screen added a param to directly switch to the databases tab (this is used when the user goes from the admin server screen to the client server screen) Fixed “Missing Server ID” notification when client server is opened with databases tab as first tab
Created server manage tab (only reinstall & suspend/unsuspend cuz there seem to be no API endpoint to toggle install status & transfer) Created server delete tab Added 2 new button types, SUCCESS (green) and WARNING (yellow) In the admin server screen now most tabs are hidden whent he server is installing
Created users & user screen Updated the AGP (Android Gradle Plugin) Table headers now properly support multi line text (previously if one text was multiline while everything else wasn’t, all the divider would have a gap on the bottom except for the multiline one) In the client server screen, settings tab the UUID is now aligned to the right Improved screen change when deleting a server/node/user/location (instead of navController.popBackStack() (which basically acts as the back button) i specifically navigate to generic screen (eg. “user” -> “users”) and remove current screen from the back history so in the case that there is no screen to back into (eg if the app is opened via a deep link or stuff like that) it will go to the generic tab anyway) Added pull to refresh in the location screen
Created nests, nest & nest egg screens For nest egg screen, created 3 tabs: Configuration Variables Install Script it was pretty easy and quick to create those cuz they’re read-only as there’s no API endpoint to edit/delete them Added a back handler in the tabbed screens so that back button now goes to the previous tab instead of the entire previous screen In the client servers screen added a switch to see others’ server (admin only) Fixed capitalization in the getNestEgg function ( eggid -> eggId )
Added optional biometric authentication so people can lock their app behind phone code or biometric verification (like fingerprint etc.)
Added updated checking For F-Droid flavor it doesn’t do anything For APK flavor it checks my git repo For Play Store flavor it uses play store com.google.android.play:app-update library Updated the app site, available at https://ptero.stefdp.com Updated the changelog & app images in the fastlane folder Added an animation when switching between loading states with circular loading
Ships:
For rating & testing the project, please first read all of the text in the release. I made an Android app to manage your self-hosted Pterodactyl Panel instance (Currently only the client side, later I’ll also add the admin side). For who doesn’t know, Pterodactyl Panel is a panel usually used to manage game servers, but it can run anything, each server is just a docker container. The most challenging part was prob downloading files, and it still confuses me tbh because on the Android Studio emulator it works fine, but when if I try it on my actual phone (Samsung A55 5G) it randomly stops after a few seconds and I can’t seem to understand why...
|
1793822021.5631883
|
1793908421.5631883
|
|
286
|
My Website by @stefdp | Stardance
|
stefdp
|
2
|
7.75
|
28
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-07-29T10:49:14Z", "hours": 3.0, "multiplier": 5.13, "payout": 16, "blessing": "neutral", "text": "I updated the webring code so that now: The webring is on the bottom right (moved neko credits from bottom right to bottom center), a bit more above the bottom so that on small screens like phones it doesn’t overlap with the credits It’s now vertical Added a new webring ( https://horser.ing , only for friends) and so i added a select to choose the ring and also a ?webring query that auto selects given ring (currently as values there’s hackclub for hc ring and horsering for the horsering) it’s wasn’t really challenging, only thing that took me a bit was find out which class added a horizontal padding to the select cuz none of my tailwind classes added it, then i found out it was DaisyUI’s btn class", "repo": "https://git.stefdp.com/Stef/personal-site", "demo": "https://stefdp.com"}, {"ship_num": 2, "ts": "2026-06-06T12:53:05Z", "hours": 1.0, "multiplier": 8.07, "payout": 12, "blessing": "neutral", "text": "I added a switch for plain text & code in the about me section and switched from nix webring to hackclub webring nothnig was really challenging, only issue i had was that the webring iframe for some reason looked good on my laptop but when i pushed to prod it got some weird white bg, couldn’t figure out how to fix it so i just ended up making my own buttons (and also added a random page button which official webring doesn’t have! :D)", "repo": "https://git.stefdp.com/Stef/personal-site", "demo": "https://stefdp.com"}]...
|
[{"post_id": 71777, "ts": "202 [{"post_id": 71777, "ts": "2026-09-21T15:03:47Z", "hours": 2.6286, "text": "Updated the main embed to add social links and page specific text/images too and also fix buttons’ urls"}, {"post_id": 70204, "ts": "2026-09-18T18:12:30Z", "hours": 1.1197, "text": "Added the new discord embed with components v2"}, {"post_id": 36934, "ts": "2026-07-29T10:42:29Z", "hours": 0.4753, "text": "Made the horizontal padding of the select smaller I legit couldn’t find what that padding was caused by cuz i didn’t have any p* classes and after like 20 mins i found out that it was the DaisyUI’s btn class that added padding-inline 🥀 so i fixed it with px-2 (which in tailwind stands for 0.5rem or 8px"}, {"post_id": 36485, "ts": "2026-07-28T16:54:50Z", "hours": 2.4244, "text": "Added the Horsering in the rings (friend only ring) Moved the neko credits in the middle Moved the webring on the right and made it vertical"}, {"post_id": 3493, "ts": "2026-06-06T13:36:40Z", "hours": 0.2644, "text": "Updated the README.md (I had forgot to update it before shipping 😭)"}, {"post_id": 3467, "ts": "2026-06-06T12:47:26Z", "hours": 1.4947, "text": "Added a “Switch to Code/Plain Text” in the about me so people who don’t know Typescript can just read it as plain text Moved from Nix Webring to Hack Club Webring since i don’t use NixOS anymore"}]...
|
Title: My Website by @stefdp | Stardance
Devlogs: Title: My Website by @stefdp | Stardance
Devlogs:
Added a “Switch to Code/Plain Text” in the about me so people who don’t know Typescript can just read it as plain text Moved from Nix Webring to Hack Club Webring since i don’t use NixOS anymore
Updated the README.md (I had forgot to update it before shipping 😭)
Added the Horsering in the rings (friend only ring) Moved the neko credits in the middle Moved the webring on the right and made it vertical
Made the horizontal padding of the select smaller I legit couldn’t find what that padding was caused by cuz i didn’t have any p* classes and after like 20 mins i found out that it was the DaisyUI’s btn class that added padding-inline 🥀 so i fixed it with px-2 (which in tailwind stands for 0.5rem or 8px
Added the new discord embed with components v2
Updated the main embed to add social links and page specific text/images too and also fix buttons’ urls
Ships:
I added a switch for plain text & code in the about me section and switched from nix webring to hackclub webring nothnig was really challenging, only issue i had was that the webring iframe for some reason looked good on my laptop but when i pushed to prod it got some weird white bg, couldn’t figure out how to fix it so i just ended up making my own buttons (and also added a random page button which official webring doesn’t have! :D)
I updated the webring code so that now: The webring is on the bottom right (moved neko credits from bottom right to bottom center), a bit more above the bottom so that on small screens like phones it doesn’t overlap with the credits It’s now vertical Added a new webring ( https://horser.ing , only for friends) and so i added a select to choose the ring and also a ?webring query that auto selects given ring (currently as values there’s hackclub for hc ring and horsering for the horsering) it’s wasn’t really challenging, only thing that took me a bit was find out which class added a horizontal padding to the select cuz none of my tailwind classes added it, then i found out it was DaisyUI’s btn class...
|
1793749683.2992563
|
1793836083.2992563
|
|
40005
|
Restart Pterodactyl GitHub Action by @stefdp | Sta Restart Pterodactyl GitHub Action by @stefdp | Stardance...
|
stefdp
|
1
|
2.0
|
13
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-07-26T11:52:02Z", "hours": 2.0, "multiplier": 6.26, "payout": 13, "blessing": "neutral", "text": "To use the app please read the README ’s “Stardance Demo” section, I explained there how to get it to run. I made a GitHub action to restart your Pterodactyl Panel server, during Stardance I added the ability to run commands or a delay before the server is restarted (or both). It wasn’t really hard as I just make multiple HTTP requests and I know the Pterodactyl API quite well since I’m also making an android app for it. I made this action mainly for the Minecraft server of a friend, so the server automatically restarts when we add a new mod in the packwiz config on git but this can actually be used by anyone with a server, no matter what they’re running (as long as their user has the permission to restart the server)", "repo": "https://git.stefdp.com/Stef/restart-ptero-action", "demo": "https://git.stefdp.com/Stef/restart-ptero-action/#stardance-demo"}]...
|
[{"post_id": 35137, "ts": "202 [{"post_id": 35137, "ts": "2026-07-26T11:44:21Z", "hours": 1.105, "text": "Added the ability to run multiple commands Updated the README Added a example workflow that works"}, {"post_id": 35070, "ts": "2026-07-26T08:07:13Z", "hours": 0.9506, "text": "Added the option to run a command before the server restarts Added the option to add a delay before the server restarts (useful with the command as the API doesn’t say when the cmd has finished running) Added the README"}]...
|
Title: Restart Pterodactyl GitHub Action by @stefd Title: Restart Pterodactyl GitHub Action by @stefdp | Stardance
Devlogs:
Added the option to run a command before the server restarts Added the option to add a delay before the server restarts (useful with the command as the API doesn’t say when the cmd has finished running) Added the README
Added the ability to run multiple commands Updated the README Added a example workflow that works
Ships:
To use the app please read the README ’s “Stardance Demo” section, I explained there how to get it to run. I made a GitHub action to restart your Pterodactyl Panel server, during Stardance I added the ability to run commands or a delay before the server is restarted (or both). It wasn’t really hard as I just make multiple HTTP requests and I know the Pterodactyl API quite well since I’m also making an android app for it. I made this action mainly for the Minecraft server of a friend, so the server automatically restarts when we add a new mod in the packwiz config on git but this can actually be used by anyone with a server, no matter what they’re running (as long as their user has the permission to restart the server)...
|
1793947734.2736619
|
1794034134.2736619
|
|
56694
|
[MOVED] Discord User Apps Bot by @stefdp | Stardan [MOVED] Discord User Apps Bot by @stefdp | Stardance...
|
stefdp
|
1
|
85.0
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-09-24T13:33:42Z", "hours": 85.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I rewrote my userApps Discord bot from TypeScript to Kotlin just because I prefer kotlin now that i’ve been using it for about a while, and in the meanwhile i also added new commands to it", "repo": "https://git.stefdp.com/Stef/userApps", "demo": "https://discord.com/oauth2/authorize?client_id=1223221223685886032"}]...
|
[{"post_id": 72794, "ts": "202 [{"post_id": 72794, "ts": "2026-09-23T19:06:22Z", "hours": 0.3492, "text": "Added environment check in the API endpoint like /status enable command Emoji envs are now correctly formatted in the error message Marked /status command as owner only"}, {"post_id": 72707, "ts": "2026-09-23T15:29:45Z", "hours": 3.7897, "text": "Rewrote the web dashboard to look better (by orangc) Added the API endpoints to manage commands on the dash side Added support for docker compose"}, {"post_id": 70873, "ts": "2026-09-19T22:10:42Z", "hours": 5.3797, "text": "Created the /help command: list all the commands of get info about a specific one Temporarily took the old dashboard and adapted it to the new framework (the html side is gonna get remade by a friend, orangc) Removed some unused envs Added TailwindCSS compiling at startup soit can be used in the dashboard"}, {"post_id": 70257, "ts": "2026-09-18T20:20:48Z", "hours": 5.9111, "text": "Created the /uptime command: display how long the bot has been online for Created the /lyrics command: get the lyrics of a song (uses lrclib.net, lrcmux and lyricsOVH as sources) Fixed /define command failing when there were too many definitions (was going over the 40 components limit) Created the main README file Added ownerOnly property to commands, so when they’re first added to the db, it sets the list of owners in the OWNERS env as allowed users Added attachment options to the /embed command (for some reasons they’re added correctly but image and thumbnail don’t display while footer and author do)"}, {"post_id": 69649, "ts": "2026-09-17T14:30:09Z", "hours": 4.295, "text": "Created the /ubdict command: get the definition of a term from the urban dictionary Created the /wikipedia command: get an article from wikipedia Created the /fact command: get a random fact Created the /joke command: get a random joke Added a util function to split strings in group of approximately X character, but instead of cutting the text at exactly X characters, it cuts at the next end of a sentence after X characters, this way a sentence is never cut in half during pagination (currently only place where it’s used, aka /wikipedia command) Added the User-Agent header to all the HTTP requests Updated HttpLoggingInterceptor to use the correct logger class"}, {"post_id": 68211, "ts": "2026-09-14T18:17:54Z", "hours": 2.95, "text": "Created the /define command: get the definition of a word Updated the /steam game command to use components v2, and also a button to show the full game description if the detailed mode is too long to fit Switched some places from if (xxx) { ... } else { null } to xxx?.let { ... }"}, {"post_id": 67479, "ts": "2026-09-13T16:26:49Z", "hours": 7.7817, "text": "Created the Get User Banner command (user): …what the name says Created the /github command (slash): get info about a GH user, repo or issue/PR Created the /weather command (slash): get the current weather of a specific place /steam game now uses buildString {} instead of adding to a array, then joining and merging it with another string"}, {"post_id": 66516, "ts": "2026-09-12T11:06:55Z", "hours": 6.5256, "text": "Created the /steam command (slash): get info about a Steam game (optional detailed mode) or user Created the /translate command (slash): convert any text from a language to another (about 131 languages available) Installed the MS Azure SDK for the /translate (slash) & Translate Message (message) commands Updated file layout for the dashboard so it looks better Updated API services file layout too Updated Kotlin from 2.4.10 to 2.4.20 and other libs"}, {"post_id": 65657, "ts": "2026-09-10T22:56:19Z", "hours": 4.5164, "text": "Running a command now increases its uses value is the anonymous analytics table Added new env variables and improved the system used to throw errors so it always kills all the processes when calling require Created the dashboard ratelimits, sessions, auth middlewares/systems Created the Discord OAuth2 login Moved kord into a Bot object so it can be used in the dashboard too if needed Created a listener for the discord webhook (stuff like bot authorized, bot deauthorized etc.) [UNTESTED] Created a util function to get the bot’s invite url Created API services for the discord OAuth2 token requesting and apprise API There’s not much frontend / UI change so ima show a pic of the dash module code ig"}, {"post_id": 65422, "ts": "2026-09-10T15:31:24Z", "hours": 5.8289, "text": "Created the /export command (slash): send the file path and export it (as well as give the file’s github url (owner only) Created the Save as Tag command (message): save a message as tag, both embeds & content Created the Convert to QR Code command (message): convert a message’s content to a QR code (either as image or text) Created the Download Voice Message command (message): as the name says, download as MP3 a user’s voice message Created the Set as Reminder command (message): set a user’s message (either content or URL) as a reminder Created the Get Message JSON command (message): get the JSON object of the message Created the Get Member Avatar command (user): get the server specific avatar of the user Created the Get User Avatar command (user): get the global avatar of the user Created the Get User Avatar Decoration command (user): get the avatar decoration of the user Created the Get Member JSON command (user): get the JSON object of the member Created the Get User JSON command (user): get the JSON object of the user Environment variables are now loaded at startup via a gradle task Added a LOG_LEVEL env to choose the level of the console output to show Created a util function for plurals Set tag name limit to 255 chars"}, {"post_id": 64121, "ts": "2026-09-08T10:02:03Z", "hours": 7.1333, "text": "Added the /tag command: save preset messages that you can then send later (they can also contain embeds) it has the following subcommands: content : set or remove the content of a tag embed : add or remove an embed from a tag delete : delete a tag export : export all your tags as a JSON file import : import the JSON file obtained from the export subcommand (in case of conflicts, the old and new tag will be previeable in the bot dashboard if enabled) list : Display all your subcommands get : Get the content & embeds of a specific subcommand Fixed/Impoved the /embed command button & modal handlers & added an ID to buttons & modals to avoid 2 diff commands handling the same interaction"}, {"post_id": 62806, "ts": "2026-09-06T10:14:43Z", "hours": 5.5831, "text": "Created the /gary command: get random images of 4 cats: Gary, Goober, Gulliber (Gully) and Garfield Created the /ping command: get the bot’s ping (pic has high ping cuz it’s running on my laptop, in Italy) Created the /botavatar command: change the bot avatar, either from a file, URL, copy from an user or copy from the bot owner Created the /colorpicker command: give an HEX, RGB or HSL color and it displays it as well as showing its HEX, RGB and HSL variants Added the /reminders command: set a reminder and the bot will send you a DM, reminder can either be single-run, multi-run and inifinitely run (the user defines an interval such as 30m , 2d15h etc., then the bot will send a DM with the reminder after this interval and will repeat it how many times the user defined it to, so if an user defines a reminder with 2h interval and 3 repeats, it will send the same reminder in 2h, 4h and 6h) (hope i explained well ) Switched database initialization from SchemaUtils to MigrationUtils this way if i edit a scheme, it’s also applied at startup instead of just creating new tables and never modifying them Made the dashboard disableable"}, {"post_id": 61179, "ts": "2026-09-03T23:53:05Z", "hours": 6.5219, "text": "Created the /minecraft command: allows to fetch Java and Bedrock edition server data (with mcstatus.io API ) Player info (with Starlight API by lunareclipse.studio ) Player skin rendered as a 3D model in different poses (with Starlight API) Created the /embed command: send anything as an embed Created the /qr command: encode some text into a QR Code (output can be an image or an ASCII text) Updated the dashboard to add a static resource /skinModels which is used for the /minecraft skin sub command to fetch custom made models Added a regex for HEX colors (matches #ffffff , #fff , ffffff and fff ) created a Minecraft object to collect all minecraft related functions Created the starlight and mcstatus.io API services & added them in the API client Update main handleRequest function to add an optional error handler"}, {"post_id": 60524, "ts": "2026-09-02T22:26:55Z", "hours": 3.5928, "text": "Added the /8ball command: ask a question and get a random answer Added topic command: get a random topic to start a conversation Added /qalc command: execute calculation using libqalculate Added /console command: run any shell command Added /animal command: get a random animal (cat, dog, fox, duck) Added /ip command: get info about an IPv4 or IPv6 address Installed the retrofit libs required to make HTTP requests Added a regex to check if a IPv4 or IPv6 is valid (took from networkingtoolbox.net ) Created util function to get the country flag & name from its code (took from my Hackatime android app)"}, {"post_id": 60238, "ts": "2026-09-02T14:13:38Z", "hours": 5.9553, "text": "Added /http command: get a HTTP status with the picture of an animal like cat, dog, goat, duck etc. Added /perms command: add/remove/list the users allowed to use a specific command Added /status command: enable/disable specific commands Added /dig : perform a dig query on a domain Added /whois : perform a WHOIS query on a domain/IP/ASN Fixed database upsert function erroring because no column was being passed as keys (primary) Moved command registration to the onReady event Installed a lib for DNS queries and a lib to check other libs updates Added a utility Domain object that contains the function to perform dig and whois queries Added utility functions to convert a ISO string, epoch seconds or Instant to discord time format"}, {"post_id": 59784, "ts": "2026-09-01T18:32:38Z", "hours": 3.5347, "text": "Created the /eval command Added the registration & handling of the commands (also checks if the user can run the command and if the command is enabled, by checking the enabled status and allowedUsers list in the command_permissions table) Installed some libs to run code at runtime (JavaScript, Python and Kotlin (used in /eval )"}, {"post_id": 59212, "ts": "2026-08-31T21:38:20Z", "hours": 4.8561, "text": "Created the base skeleton with the bot (w/ events), web dashboard (rn just shows “WIP” text) and database with the schemes & some helper functions For the Discord bot i’m using the Kord library For the web dashboard i’m using the Ktor library This is the first time i use either of those 2 libs so my usage may not be the best"}]...
|
Title: [MOVED] Discord User Apps Bot by @stefdp | Title: [MOVED] Discord User Apps Bot by @stefdp | Stardance
Devlogs:
Created the base skeleton with the bot (w/ events), web dashboard (rn just shows “WIP” text) and database with the schemes & some helper functions For the Discord bot i’m using the Kord library For the web dashboard i’m using the Ktor library This is the first time i use either of those 2 libs so my usage may not be the best
Created the /eval command Added the registration & handling of the commands (also checks if the user can run the command and if the command is enabled, by checking the enabled status and allowedUsers list in the command_permissions table) Installed some libs to run code at runtime (JavaScript, Python and Kotlin (used in /eval )
Added /http command: get a HTTP status with the picture of an animal like cat, dog, goat, duck etc. Added /perms command: add/remove/list the users allowed to use a specific command Added /status command: enable/disable specific commands Added /dig : perform a dig query on a domain Added /whois : perform a WHOIS query on a domain/IP/ASN Fixed database upsert function erroring because no column was being passed as keys (primary) Moved command registration to the onReady event Installed a lib for DNS queries and a lib to check other libs updates Added a utility Domain object that contains the function to perform dig and whois queries Added utility functions to convert a ISO string, epoch seconds or Instant to discord time format
Added the /8ball command: ask a question and get a random answer Added topic command: get a random topic to start a conversation Added /qalc command: execute calculation using libqalculate Added /console command: run any shell command Added /animal command: get a random animal (cat, dog, fox, duck) Added /ip command: get info about an IPv4 or IPv6 address Installed the retrofit libs required to make HTTP requests Added a regex to check if a IPv4 or IPv6 is valid (took from networkingtoolbox.net ) Created util function to get the country flag & name from its code (took from my Hackatime android app)
Created the /minecraft command: allows to fetch Java and Bedrock edition server data (with mcstatus.io API ) Player info (with Starlight API by lunareclipse.studio ) Player skin rendered as a 3D model in different poses (with Starlight API) Created the /embed command: send anything as an embed Created the /qr command: encode some text into a QR Code (output can be an image or an ASCII text) Updated the dashboard to add a static resource /skinModels which is used for the /minecraft skin sub command to fetch custom made models Added a regex for HEX colors (matches #ffffff , #fff , ffffff and fff ) created a Minecraft object to collect all minecraft related functions Created the starlight and mcstatus.io API services & added them in the API client Update main handleRequest function to add an optional error handler
Created the /gary command: get random images of 4 cats: Gary, Goober, Gulliber (Gully) and Garfield Created the /ping command: get the bot’s ping (pic has high ping cuz it’s running on my laptop, in Italy) Created the /botavatar command: change the bot avatar, either from a file, URL, copy from an user or copy from the bot owner Created the /colorpicker command: give an HEX, RGB or HSL color and it displays it as well as showing its HEX, RGB and HSL variants Added the /reminders command: set a reminder and the bot will send you a DM, reminder can either be single-run, multi-run and inifinitely run (the user defines an interval such as 30m , 2d15h etc., then the bot will send a DM with the reminder after this interval and will repeat it how many times the user defined it to, so if an user defines a reminder with 2h interval and 3 repeats, it will send the same reminder in 2h, 4h and 6h) (hope i explained well ) Switched database initialization from SchemaUtils to MigrationUtils this way if i edit a scheme, it’s also applied at startup instead of just creating new tables and never modifying them Made the dashboard disableable
Added the /tag command: save preset messages that you can then send later (they can also contain embeds) it has the following subcommands: content : set or remove the content of a tag embed : add or remove an embed from a tag delete : delete a tag export : export all your tags as a JSON file import : import the JSON file obtained from the export subcommand (in case of conflicts, the old and new tag will be previeable in the bot dashboard if enabled) list : Display all your subcommands get : Get the content & embeds of a specific subcommand Fixed/Impoved the /embed command button & modal handlers & added an ID to buttons & modals to avoid 2 diff commands handling the same interaction
Created the /export command (slash): send the file path and export it (as well as give the file’s github url (owner only) Created the Save as Tag command (message): save a message as tag, both embeds & content Created the Convert to QR Code command (message): convert a message’s content to a QR code (either as image or text) Created the Download Voice Message command (message): as the name says, download as MP3 a user’s voice message Created the Set as Reminder command (message): set a user’s message (either content or URL) as a reminder Created the Get Message JSON command (message): get the JSON object of the message Created the Get Member Avatar command (user): get the server specific avatar of the user Created the Get User Avatar command (user): get the global avatar of the user Created the Get User Avatar Decoration command (user): get the avatar decoration of the user Created the Get Member JSON command (user): get the JSON object of the member Created the Get User JSON command (user): get the JSON object of the user Environment variables are now loaded at startup via a gradle task Added a LOG_LEVEL env to choose the level of the console output to show Created a util function for plurals Set tag name limit to 255 chars
Running a command now increases its uses value is the anonymous analytics table Added new env variables and improved the system used to throw errors so it always kills all the processes when calling require Created the dashboard ratelimits, sessions, auth middlewares/systems Created the Discord OAuth2 login Moved kord into a Bot object so it can be used in the dashboard too if needed Created a listener for the discord webhook (stuff like bot authorized, bot deauthorized etc.) [UNTESTED] Created a util function to get the bot’s invite url Created API services for the discord OAuth2 token requesting and apprise API There’s not much frontend / UI change so ima show a pic of the dash module code ig
Created the /steam command (slash): get info about a Steam game (optional detailed mode) or user Created the /translate command (slash): convert any text from a language to another (about 131 languages available) Installed the MS Azure SDK for the /translate (slash) & Translate Message (message) commands Updated file layout for the dashboard so it looks better Updated API services file layout too Updated Kotlin from 2.4.10 to 2.4.20 and other libs
Created the Get User Banner command (user): …what the name says Created the /github command (slash): get info about a GH user, repo or issue/PR Created the /weather command (slash): get the current weather of a specific place /steam game now uses buildString {} instead of adding to a array, then joining and merging it with another string
Created the /define command: get the definition of a word Updated the /steam game command to use components v2, and also a button to show the full game description if the detailed mode is too long to fit Switched some places from if (xxx) { ... } else { null } to xxx?.let { ... }
Created the /ubdict command: get the definition of a term from the urban dictionary Created the /wikipedia command: get an article from wikipedia Created the /fact command: get a random fact Created the /joke command: get a random joke Added a util function to split strings in group of approximately X character, but instead of cutting the text at exactly X characters, it cuts at the next end of a sentence after X characters, this way a sentence is never cut in half during pagination (currently only place where it’s used, aka /wikipedia command) Added the User-Agent header to all the HTTP requests Updated HttpLoggingInterceptor to use the correct logger class
Created the /uptime command: display how long the bot has been online for Created the /lyrics command: get the lyrics of a song (uses lrclib.net, lrcmux and lyricsOVH as sources) Fixed /define command failing when there were too many definitions (was going over the 40 components limit) Created the main README file Added ownerOnly property to commands, so when they’re first added to the db, it sets the list of owners in the OWNERS env as allowed users Added attachment options to the /embed command (for some reasons they’re added correctly but image and thumbnail don’t display while footer and author do)
Created the /help command: list all the commands of get info about a specific one Temporarily took the old dashboard and adapted it to the new framework (the html side is gonna get remade by a friend, orangc) Removed some unused envs Added TailwindCSS compiling at startup soit can be used in the dashboard
Rewrote the web dashboard to look better (by orangc) Added the API endpoints to manage commands on the dash side Added support for docker compose
Added environment check in the API endpoint like /status enable command Emoji envs are now correctly formatted in the error message Marked /status command as owner only
Ships:
I rewrote my userApps Discord bot from TypeScript to Kotlin just because I prefer kotlin now that i’ve been using it for about a while, and in the meanwhile i also added new commands to it...
|
1793800465.353085
|
1793886865.353085
|
|
66010
|
[MOVED] CollabNotes by @stefdp | Stardance
|
stefdp
|
0
|
14.23
|
0
|
[]
|
[{"post_id": 76820, "ts": "202 [{"post_id": 76820, "ts": "2026-10-04T18:24:08Z", "hours": 4.8381, "text": "Fixed auth middleware (it was using an invalid SQL query) in GET /api/email/request the token is now URL decoded before it’s used Updated POST /api/login to return a 204 instead of redirection Added pending email database keys for the users who are changing their mail Created the POST /api/verify-email endpoint to verify the mail (either at register or update mail) Added Password4J config file and set a salt length of 64 Created the notes table and the sharing codes table fixed Thymeleaf using wrong paths for frontend file locations Created the POST /api/account/update-email endpoint to let users change their mail Created the GET /api/notes endpoint to let the user see the notes he has access to Created the POST /api/notes endpoint to let the user create a note under his user Created the GET /api/notes/{noteId} endpoint to get the data of a specific note (if the user has access to it) Created the DELETE /api/notes/{noteId} endpoint to let a user delete his own notes (not the ones made by other even if he has access to them) Created the POST /api/notes/{noteId}/join endpoint to let a user join a note via its sharing code Created the POST /api/notes/{noteId}/share endpoint to create a sharing code for the note (each code is one-time use only) Created the DELETE /api/notes/{noteId}/share endpoint to delete a sharing code for the note (note owner only) Created the POST /api/notes/{noteId}/leave endpoint to let a user leave a note on its own Created the POST /api/notes/{noteId}/kick endpoint to let the note owner kick someone from the note Created a util function to validate a string for all common password requirements (min 8 chars, a number, a uppercase letter, a lowercase letter and a special character) Created a job to clear pending mails that haven’t been verified in over 10 mins Fixed route patterns, when inside a route(\"/...\") { ... } i was using get(\"/\") { ... } instead of get { ... } and this caused the base route to not exist (like /api/route ) but only the one with trailing slash (like /api/route/ ) once again no frontend yet so here’s some of the code"}, {"post_id": 75021, "ts": "2026-09-28T21:31:10Z", "hours": 3.9217, "text": "Installed a lib to hash & salt user passwords Moved all routes to a routes folder Update verification data in the DB schema Created a PublicDatabaseUser data class that doesn’t contain sensitive info such as password Created a util Crypto object to hash & salt strings Updated the verification mail template Fixed Email class not seeing the template file Email verification endpoint now shows a proper html page (html not made yet tho) All routes now include their method in the file and function name Created the following endpoints: GET /api/request-email POST /api/login GET /api/account PATCH /api/account DELETE /api/account None of those changes have been tested yet once again no frontend yet so just code screenshots"}, {"post_id": 74536, "ts": "2026-09-27T16:12:37Z", "hours": 5.4689, "text": "Initialized the app by taking & modifying some stuff from my other apps (mainly the userApps discord bot) ( EnvVariable enum, Random object, build process w/ tailwind & envs setup, middlewares, AppDatabase object) Created a routes skeleton to show how it will look approximately Created the API endpoint to register Created the API endpoint to logout Added an Email class used to validate emails, check for duplicates and send the verification code Added a job that every 5 minutes checks for users that have not verified their mail and if they haven’t verified in 10 mins, their account is deleted Installed a library to send emails there’s no frontend yet so i’ll show some of the API routes skeletons"}]...
|
Title: [MOVED] CollabNotes by @stefdp | Stardance
Title: [MOVED] CollabNotes by @stefdp | Stardance
Devlogs:
Initialized the app by taking & modifying some stuff from my other apps (mainly the userApps discord bot) ( EnvVariable enum, Random object, build process w/ tailwind & envs setup, middlewares, AppDatabase object) Created a routes skeleton to show how it will look approximately Created the API endpoint to register Created the API endpoint to logout Added an Email class used to validate emails, check for duplicates and send the verification code Added a job that every 5 minutes checks for users that have not verified their mail and if they haven’t verified in 10 mins, their account is deleted Installed a library to send emails there’s no frontend yet so i’ll show some of the API routes skeletons
Installed a lib to hash & salt user passwords Moved all routes to a routes folder Update verification data in the DB schema Created a PublicDatabaseUser data class that doesn’t contain sensitive info such as password Created a util Crypto object to hash & salt strings Updated the verification mail template Fixed Email class not seeing the template file Email verification endpoint now shows a proper html page (html not made yet tho) All routes now include their method in the file and function name Created the following endpoints: GET /api/request-email POST /api/login GET /api/account PATCH /api/account DELETE /api/account None of those changes have been tested yet once again no frontend yet so just code screenshots
Fixed auth middleware (it was using an invalid SQL query) in GET /api/email/request the token is now URL decoded before it’s used Updated POST /api/login to return a 204 instead of redirection Added pending email database keys for the users who are changing their mail Created the POST /api/verify-email endpoint to verify the mail (either at register or update mail) Added Password4J config file and set a salt length of 64 Created the notes table and the sharing codes table fixed Thymeleaf using wrong paths for frontend file locations Created the POST /api/account/update-email endpoint to let users change their mail Created the GET /api/notes endpoint to let the user see the notes he has access to Created the POST /api/notes endpoint to let the user create a note under his user Created the GET /api/notes/{noteId} endpoint to get the data of a specific note (if the user has access to it) Created the DELETE /api/notes/{noteId} endpoint to let a user delete his own notes (not the ones made by other even if he has access to them) Created the POST /api/notes/{noteId}/join endpoint to let a user join a note via its sharing code Created the POST /api/notes/{noteId}/share endpoint to create a sharing code for the note (each code is one-time use only) Created the DELETE /api/notes/{noteId}/share endpoint to delete a sharing code for the note (note owner only) Created the POST /api/notes/{noteId}/leave endpoint to let a user leave a note on its own Created the POST /api/notes/{noteId}/kick endpoint to let the note owner kick someone from the note Created a util function to validate a string for all common password requirements (min 8 chars, a number, a uppercase letter, a lowercase letter and a special character) Created a job to clear pending mails that haven’t been verified in over 10 mins Fixed route patterns, when inside a route("/...") { ... } i was using get("/") { ... } instead of get { ... } and this caused the base route to not exist (like /api/route ) but only the one with trailing slash (like /api/route/ ) once again no frontend yet so here’s some of the code...
|
1793710194.4091475
|
1794314994.4091475
|