looks nice, but the vote buttons look too big
Jerboa
Jerboa is a native-android client for Lemmy, built using the native android framework, Jetpack Compose.
Warning: You can submit issues, but between Lemmy and lemmy-ui, I probably won't have too much time to work on them. Learn jetpack compose like I did if you want to help make this app better.
Built With
Features
- Open source, AGPL License.
Installation / Releases
Support / Donate
Jerboa is made by Lemmy's developers, and is free, open-source software, meaning no advertising, monetizing, or venture capital, ever. Your donations directly support full-time development of the project.
Crypto
- bitcoin:
1Hefs7miXS5ff5Ck5xvmjKjXf5242KzRtK
- ethereum:
0x400c96c96acbC6E7B3B43B1dc1BB446540a88A01
- monero:
41taVyY6e1xApqKyMVDRVxJ76sPkfZhALLTjRvVKpaAh2pBd4wv9RgYj1tSPrx8wc6iE1uWUfjtQdTmTy2FGMeChGVKPQuV
- cardano:
addr1q858t89l2ym6xmrugjs0af9cslfwvnvsh2xxp6x4dcez7pf5tushkp4wl7zxfhm2djp6gq60dk4cmc7seaza5p3slx0sakjutm
Contact
I agree. If it were a bit more compact, I'd like it more.
That's exactly my viewpoint.
I'd rather prefer like/unlike arrows somehow smaller.
Some quick unrefined feedback (my remarks, no bad ill intended):
UX:
- It takes up a lot screen real estate without giving much info back:
- Each posts displays: Title, username, communityname (twice), communityinstance, embed preview or post body, What Jerboa now displays as info in card layout: Community(icon/name/instance), User (name, icon, bot, mod), Total score, (up/down)votes, post title, post body/ post preview, time posted/edited, read/unread, pinned, deleted, featured, saved, already (upvoted/downvoted), total comments and new comments
- Community name and username are bit too small, hard to read, makes touch targets very small thus hard to hit
- Title fontsize too big, long titles will reap havoc (And believe me they can get long, especially the mastodons federated posts as it includes a link each time)
- No user actions buttons,
- to reiterate, takes up lots of precious screen real estate. (It's why current doesn't have padding between posts, only when needed). It's tough to balance: giving loads of information in easy to digest format. Its why currently it uses lots of assumptions, lack of some information can give you more, (ex: doesn't show upvotes/downvotes if it are all upvotes, community instance not included if its your home instance )
UI:
- Don't like the upvote downvote , too big
Interesting filter prototype at the top there? This scrolls with the feed I assume, so once you scrolled a bit and you want to change the filter you have to scroll all the way up again? And if it popups like the topbar, then it would take up more than 10% of your screen each time
UI/UX Design is hard, definitely what I struggle the most with while contributing to Jerboa. UI wise you can't please everyone ,ppl have preferences. (The real reason why full search + filters isn't implemented yet, haven't had the time yet to prototype it, which is the biggest time sink, the actually functionality is rather simple)
I agree with all points, thanks for writting them down. Current UI is great for me.
Too much whitespace
I personally prefer it the way it is now
I'd rather see some work on the crashing over a ui refresh
What crashes do you experience? Could you go to settings > About > Crash logs and sent the recents ones to me
Here's the most recent one. It happens once or twice a day, usually when expanding or scrolling in the replies. They're all the same exception, with the exception of the key number, but if more traces will help you I can can send all of them.
Stacktrace
java.lang.IllegalArgumentException: Key "3764992" was already used. If you are using LazyColumn/Row please make sure you provide a unique key for each item. at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$Scope.subcompose(Unknown Source:182) at androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScopeImpl.measure-0kLqBqw(Unknown Source:33) at androidx.compose.foundation.lazy.LazyListKt$rememberLazyListMeasurePolicy$1$1$measuredItemProvider$1.getAndMeasure(Unknown Source:18) at androidx.compose.foundation.lazy.LazyListKt$rememberLazyListMeasurePolicy$1$1.invoke(Unknown Source:617) at androidx.navigation.compose.NavHostKt$NavHost$14$1.invoke(SourceFile:17) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1.measure-3p2s80s(Unknown Source:91) at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(Unknown Source:45) at androidx.compose.material3.ComposableSingletons$AppBarKt$lambda-2$1.invoke-3p2s80s(Unknown Source:60) at androidx.compose.material3.ComposableSingletons$AppBarKt$lambda-2$1.invoke(SourceFile:73) at androidx.compose.ui.layout.LayoutModifierImpl.measure-3p2s80s(Unknown Source:12) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(Unknown Source:10) at androidx.compose.material3.ComposableSingletons$AppBarKt$lambda-2$1.invoke-3p2s80s(Unknown Source:19) at androidx.compose.material3.ComposableSingletons$AppBarKt$lambda-2$1.invoke(SourceFile:76) at androidx.compose.ui.layout.LayoutModifierImpl.measure-3p2s80s(Unknown Source:12) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(Unknown Source:10) at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(Unknown Source:5) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(Unknown Source:10) at androidx.compose.foundation.layout.PaddingNode.measure-3p2s80s(Unknown Source:37) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(Unknown Source:10) at okhttp3.internal.http2.Http2Connection$1.invoke(SourceFile:17) at okhttp3.internal.http2.Http2Connection$1.invoke(SourceFile:13) at kotlin.UNINITIALIZED_VALUE.observe(Unknown Source:63) at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(Unknown Source:66) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(Unknown Source:75) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(Unknown Source:12) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(Unknown Source:109) at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA(Unknown Source:17) at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout-0kLqBqw(Unknown Source:60) at androidx.compose.ui.platform.AndroidComposeView.measureAndLayout-0kLqBqw(Unknown Source:12) at androidx.compose.ui.node.LayoutNode.forceRemeasure(Unknown Source:40) at androidx.compose.foundation.MagnifierKt$magnifier$4$3.invoke(SourceFile:27) at androidx.compose.foundation.MagnifierKt$magnifier$4$3.invoke(SourceFile:105) at androidx.compose.foundation.gestures.DefaultScrollableState$scrollScope$1.scrollBy(Unknown Source:16) at androidx.compose.runtime.RecomposeScopeImpl$end$1$2.invoke(Unknown Source:359) at androidx.compose.foundation.AndroidEdgeEffectOverscrollEffect.applyToScroll-Rhakbz0(Unknown Source:327) at androidx.compose.foundation.gestures.ScrollingLogic.dispatchScroll-3eAAhYA(Unknown Source:49) at androidx.compose.foundation.gestures.ScrollDraggableState.dragBy(Unknown Source:15) at androidx.compose.foundation.gestures.DraggableNode$pointerInputNode$1$1$1$1.invokeSuspend(Unknown Source:81) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(Unknown Source:8) at kotlinx.coroutines.DispatchedTask.run(Unknown Source:109) at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(Unknown Source:22) at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(Unknown Source:9) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1229) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239) at android.view.Choreographer.doCallbacks(Choreographer.java:899) at android.view.Choreographer.doFrame(Choreographer.java:827) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7918) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.ui.platform.MotionDurationScaleImpl@d81cb45, androidx.compose.runtime.BroadcastFrameClock@890c29a, StandaloneCoroutine{Cancelling}@e09f7cb, AndroidUiDispatcher@5c08ba8]
END of stacktrace
Thread info
Name: main ID: 2 State: RUNNABLE Priority: 5 Thread group name: main Thread group parent: system Thread group active count: 39 Thread time: 0 hr 6 min, 7 sec
END of thread info
Device info
Report ID: 8e31d58f-c71f-4a1a-baf9-3e0d403f2f2f Device ID: f08fa57315663069 Application version: 48 Default launcher: com.android.settings Timezone name: Eastern Standard Time Timezone ID: America/New_York Version release: 13 Version incremental : 10385117 Version SDK: 33 Board: redfin Bootloader: r3-0.5-9825705 Brand: google CPU ABIS 32: armeabi-v7a, armeabi CPU ABIS 64: arm64-v8a Supported ABIS: arm64-v8a, armeabi-v7a, armeabi Device: redfin Display: TQ3A.230805.001.A2 Fingerprint: google/redfin/redfin:13/TQ3A.230805.001.A2/10385117:user/release-keys Hardware: redfin Host: abfarm-release-2004-0198 ID: TQ3A.230805.001.A2 Manufacturer: Google Product: redfin Build time: 1687810840000 Build time formatted: 26-06-2023 16:20:40 Type: user Radio: g7250-00258-230518-B-10157620,g7250-00258-230518-B-10157620 Tags: release-keys User: android-build User IDs: N/A Is sustained performance mode supported: No Is in power save mode: No Is in interactive state: Yes Is ignoring battery optimizations: No Thermal status: STATUS_NONE Location power save mode: MODE_NO_CHANGE Is device idle: No Battery percentage: 81 Battery remaining time: N/A Is battery charging: No Is device rooted: No CPU Model: Qualcomm Technologies, Inc LITO Number of CPU cores: 8 Up time with sleep: 327 hr 22 min, 56 sec Up time without sleep: 160 hr 38 min, 24 sec
END of Device info
Exit reasons
Exit reason #1
Description: null
Importance: PERCEPTIBLE
Reason: SIGNALED
Timestamp: 29-09-2023 03:20:43
END of exit reason #1
Exit reason #2
Description: remove task
Importance: CACHED
Reason: USER_REQUESTED
Timestamp: 28-09-2023 21:45:50
END of exit reason #2
Exit reason #3
Description: stop com.jerboa due to installPackageLI
Importance: CACHED
Reason: USER_REQUESTED
Timestamp: 28-09-2023 09:13:11
END of exit reason #3
END of exit reasons
Application info
App name: Jerboa Version code: 48 Version name: 0.0.48 Package name: com.jerboa Short package name: jerboa Flavor: N/A Signatures: nORRaWmGNmrBj18PL/p3svEr/s4= Is debuggable: No First installed: 07-06-2023 20:24:35 Last updated: 28-09-2023 09:13:11 Requested permissions: android.permission.ACCESS_NETWORK_STATE, android.permission.INTERNET, android.permission.READ_MEDIA_AUDIO, android.permission.READ_MEDIA_IMAGES, android.permission.READ_MEDIA_VIDEO, com.jerboa.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION Default prefs: N/A Default prefs: N/A
END of Application info
Currently running foreground/background processes
N/A
END of running foreground/background processes info
There is a fix for that one in review.
Oh great. Love the app hope I didnt come across as too critical
Looks absolutely banging mate