An app for catching up on things.

Overview

CatchUp

An app for catching up on things.

https://www.zacsweers.dev/catching-up-on-catchup-introduction/

Motivations

There's a lot of services I like reading up on throughout the day. Most of these services have dedicated apps for consuming them, but often times I just want to skim the front page and only deep dive occasionally. Enter CatchUp: a high level presentation of the "front page" of several services in short form, and intelligent deeplinking into dedicated apps if you want to go further.

CatchUp is not an all-purpose client for each of these services, just the concierge for at-a-glance details and router for getting on your way. It does not support login for any service, it does not support customization/filtering of their feed. CatchUp is dumb, and you should use one of the many great dedicated apps for this if you want more integration features.

CatchUp is also very much a testing ground for things I personally dive into, from architecture, libraries, patterns, API quirks, and more. It's been a very fun project to spike test new things.

Features

  • Multiple services
  • Hacker News
  • Reddit
  • Medium
  • Product Hunt
  • Slashdot
  • Designer News
  • Dribbble
  • GitHub
  • Infinite scrolling on supported services
  • Pleasant, simple, consistent UI for across services
  • Night mode
  • Smart deeplinking into dedicated apps

Technologies

  • Kotlin
  • RxJava 2/AutoDispose
  • Debugging tooling as a first class citizen in the debug build
  • Leak Canary, Scalpel, debug drawer, Flipper, bug reporting, the works
  • AndroidX/Jetpack
  • Dagger 2 + Hilt
  • One of the more interesting parts of CatchUp is that its service architecture is a Dagger-powered plugin system
  • Room
  • Firebase
  • Coil
  • Apollo GraphQL
  • Standard Square buffet of Okio/OkHttp 3/Retrofit 2/Moshi
  • Inspector
  • Anvil
  • KSP

There's a lot of neat/interesting little tidbits in the CatchUp source code that I plan to write a mini blog series about. Each service has its own nuances that make them unique to work with in code.

Testing

While this is a personal pet project, extensive tests can be found here.

Influences

This app owes a lot of its inspiration, implementation details, and general inner workings to the work of others. Particularly:

Development

If you'd like to build CatchUp locally, you should be able to just clone and build with no issues. The project requires JDK 11 or higher.

CatchUp tends to keep up with Android Studio canaries, so you may have to use a canary version. Check the Android Gradle Plugin SharedBuildVersions.agp version in buildSrc/build.gradle.kts.

If you want to build with working services, some require API keys. See the wiki for more details on which services require keys.

Bug fixes are always welcome. Tests are too if you're into that kinda thing, but I'm not actively trying to make this project a shining icon of TDD. For new features or otherwise significant work, please discuss in an issue first.

License

Copyright (C) 2017 Zac Sweers

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Convert list_item_general to use ConstraintLayout

    Convert list_item_general to use ConstraintLayout

    I've read your complaints about ConstraintLayout and I've been converting lately lots of our legacy layouts to ConstraintLayout, so I thought in giving you a hand.

    I tried it in emulator and it looks like this, hope it looks fine.

    screenshot_1508789195

    opened by R4md4c 20
  • Force navigation bar background to match status bar in dark theme

    Force navigation bar background to match status bar in dark theme

    Hi,

    Thank you so much for this app, I've been using it for a few days now ! I really enjoy the dark theme, but my shiny new Galaxy S8 has a default white navigation bar which makes this theme... weird 😄

    screenshot_20171026-210602

    I fixed this by setting the android:navigationBarColor to black for the night theme. It works great, but there may be more elegant ways of doing it.

    It should have no effect on phones with a black navigation bar as default (Pixel, ...). Note that on those phones, you have the opposite "problem" of having a dark navigation bar for the "light" theme, but it does feel less of a problem as it is the standard behavior.

    ps : I'm not sure what's the correct way of contributing on such issues. Submitting the PR felt the right way, but should I create an associated issue ?

    opened by anicolas 11
  • A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution

    A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution

    Repro:

    git clone https://github.com/ZacSweers/CatchUp cd CatchUp gradlew assembleDebug

    Error:

    > Task :app:kaptDebugKotlin
    warning: Current JDK version 1.8.0_181-b13 has a bug (https://bugs.openjdk.java.net/browse/JDK-8007720) that prevents(source unavailable)
    (source unavailable)
    (source unavailable)
    /Users/<>/repo/CatchUp/app/build/generated/source/kaptKotlin/debug/io/sweers/catchup/data/smmry/model/SuccessJsonAdapter.kt:0: error: cannot find symbol
    
      symbol:   class Success
      location: class SuccessJsonAdapter(source unavailable)
    (source unavailable)
    (source unavailable)
    /Users/<>/repo/CatchUp/app/build/generated/source/kaptKotlin/debug/io/sweers/catchup/data/smmry/model/SuccessJsonAdapter.kt:0: error: cannot find symbol
    
      symbol:   class Success
      location: class SuccessJsonAdapter[WARN] Incremental annotation processing requested, but support is disabled because the following processors are not incremental: com.squareup.moshi.kotlin.codegen.JsonClassCodegenProcessor (NON_INCREMENTAL), javaslang.match.PatternsProcessor (NON_INCREMENTAL).
    
    > Task :app:kaptDebugKotlin FAILED
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':app:kaptDebugKotlin'.
    > A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
       > java.lang.reflect.InvocationTargetException (no error message)
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    
    * Get more help at https://help.gradle.org
    
    BUILD FAILED in 1m 45s
    
    
    opened by jaredsburrows 7
  • Gifs duplication issue when long pressing

    Gifs duplication issue when long pressing

    When long pressing on multiple gifs (one after another) the newly selected gif is copied to the position of previous as seen here:

    preview

    Running on Android 7.1

    bug 
    opened by Tunous 7
  • Problems setting up the project

    Problems setting up the project

    I tried importing CatchUp in Android Studio but seems like AS has a hard time figuring out the project structure. Modules don't show up the way they usually do in a multi-module project.

    Some info: I was given two dialogs while importing the project. One to select the gradle wrapper, to which i selected the default gradle wrapper. The other was about which modules to include, the options being "CatchUp (root module)" and "buildSrc".

    Am I missing something?

    opened by ShaishavGandhi 6
  • Audit to match android kotlin style guide

    Audit to match android kotlin style guide

    I think the project mostly aligns with this already, but worth a look now that we have a style guide to point to - https://android.github.io/kotlin-guides/style.html

    help wanted 
    opened by ZacSweers 6
  • Make sure to call FirebaseApp.initializeApp(Context) first.

    Make sure to call FirebaseApp.initializeApp(Context) first.

    Hello, Why this issue appear on app lunching time?

    Android studio 3.0 canary 4. kotlin plugin Version: 1.1.2-4

     java.lang.RuntimeException: Unable to create application io.sweers.catchup.app.DebugCatchUpApplication: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process io.sweers.catchup.debug. Make sure to call FirebaseApp.initializeApp(Context) first.
                                                                                 at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5793)
                                                                                 at android.app.ActivityThread.-wrap1(Unknown Source:0)
                                                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1661)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:105)
                                                                                 at android.os.Looper.loop(Looper.java:164)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:6540)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
                                                                              Caused by: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process io.sweers.catchup.debug. Make sure to call FirebaseApp.initializeApp(Context) first.
                                                                                 at com.google.firebase.FirebaseApp.getInstance(Unknown Source:54)
                                                                                 at com.google.firebase.remoteconfig.FirebaseRemoteConfig.getInstance(Unknown Source:4)
                                                                                 at io.sweers.catchup.app.ApplicationModule$Companion.provideRemoteConfig(ApplicationModule.kt:70)
                                                                                 at io.sweers.catchup.app.ApplicationModule.provideRemoteConfig(Unknown Source:26)
                                                                                 at io.sweers.catchup.app.ApplicationModule_ProvideRemoteConfigFactory.get(ApplicationModule_ProvideRemoteConfigFactory.java:25)
                                                                                 at io.sweers.catchup.app.ApplicationModule_ProvideRemoteConfigFactory.get(ApplicationModule_ProvideRemoteConfigFactory.java:10)
                                                                                 at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
                                                                                 at io.sweers.catchup.app.DaggerApplicationComponent.injectCatchUpApplication(DaggerApplicationComponent.java:389)
                                                                                 at io.sweers.catchup.app.DaggerApplicationComponent.inject(DaggerApplicationComponent.java:368)
                                                                                 at io.sweers.catchup.app.CatchUpApplication.onCreate(CatchUpApplication.kt:64)
                                                                                 at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1118)
                                                                                 at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5790)
                                                                                 at android.app.ActivityThread.-wrap1(Unknown Source:0) 
                                                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1661) 
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:105) 
                                                                                 at android.os.Looper.loop(Looper.java:164) 
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:6540) 
                                                                                 at java.lang.reflect.Method.invoke(Native Method) 
                                                                                 at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 
    
    opened by ChrisBaker995 6
  • Drop Jetifier

    Drop Jetifier

    j8 ./gradlew clean -Pandroid.enableJetifier=false canIDropJetifier --no-build-cache
    
    Cannot drop Jetifier due to following external dependencies:
    
    * com.android.support:support-annotations:28.0.0
    
    * CatchUp.libraries:base-ui:unspecified
    
    * CatchUp.libraries:smmry:unspecified
    
    * com.mattprecious.telescope:telescope:2.1.0
    
    * com.facebook.flipper:flipper:0.26.0
    
    * com.facebook.flipper:flipper-network-plugin:0.26.0
    
    * me.saket:flick:1.5.0
    
    * com.f2prateek.rx.preferences2:rx-preferences:2.0.0
    
    * com.google.dagger:dagger-android:2.25.2
    
    * com.google.dagger:dagger-android-support:2.25.2
    
    opened by ZacSweers 5
  • Can't build from master - Failed to generate Apollo classes

    Can't build from master - Failed to generate Apollo classes

    Attempting to build from master I get the following error:

    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':services:github:generateReleaseApolloClasses'.
    > Failed to parse GraphQL schema introspection query from `.\CatchUp\services\github\src\main\graphql\io\sweers\catchup\service\github\schema.json`
    
    * Try:
    Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    
    * Exception is:
    org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':services:github:generateReleaseApolloClasses'.
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:205)
    	at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:263)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:203)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:184)
    	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
    	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
    	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
    	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
    	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
    	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
    	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
    	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
    	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
    	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
    	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
    	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
    	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:372)
    	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:359)
    	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:352)
    	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:338)
    	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
    	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
    	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
    	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
    	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    Caused by: java.lang.RuntimeException: Failed to parse GraphQL schema introspection query from `.\CatchUp\services\github\src\main\graphql\io\sweers\catchup\service\github\schema.json`
    	at com.apollographql.apollo.compiler.parser.Schema$Companion.parse(Schema.kt:145)
    	at com.apollographql.apollo.compiler.parser.Schema.parse(Schema.kt)
    	at com.apollographql.apollo.compiler.parser.Schema$parse.call(Unknown Source)
    	at com.apollographql.apollo.gradle.ApolloCodegenTask.generateClasses(ApolloCodegenTask.groovy:65)
    	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
    	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:49)
    	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:42)
    	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
    	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:727)
    	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:694)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.run(ExecuteActionsTaskExecuter.java:568)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
    	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:553)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:536)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:109)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:276)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:265)
    	at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$1(ExecuteStep.java:33)
    	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:33)
    	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
    	at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:63)
    	at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:35)
    	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:49)
    	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:34)
    	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:43)
    	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)
    	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)
    	at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:34)
    	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:44)
    	at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:54)
    	at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:38)
    	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49)
    	at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:153)
    	at org.gradle.internal.execution.steps.CacheStep.executeAndStoreInCache(CacheStep.java:129)
    	at org.gradle.internal.execution.steps.CacheStep.lambda$executeWithCache$2(CacheStep.java:107)
    	at org.gradle.internal.execution.steps.CacheStep.lambda$executeWithCache$3(CacheStep.java:107)
    	at org.gradle.internal.Try$Success.map(Try.java:162)
    	at org.gradle.internal.execution.steps.CacheStep.executeWithCache(CacheStep.java:76)
    	at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:66)
    	at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:41)
    	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:44)
    	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:33)
    	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)
    	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)
    	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:92)
    	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:85)
    	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)
    	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:39)
    	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:76)
    	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)
    	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)
    	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)
    	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:94)
    	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49)
    	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:79)
    	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:53)
    	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:74)
    	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:78)
    	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:78)
    	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:34)
    	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:39)
    	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:40)
    	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:28)
    	at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:192)
    	... 30 more
    Caused by: com.squareup.moshi.JsonEncodingException: Use JsonReader.setLenient(true) to accept malformed JSON at path $
    	at com.squareup.moshi.JsonReader.syntaxError(JsonReader.java:233)
    	at com.squareup.moshi.JsonUtf8Reader.checkLenient(JsonUtf8Reader.java:1051)
    	at com.squareup.moshi.JsonUtf8Reader.doPeek(JsonUtf8Reader.java:366)
    	at com.squareup.moshi.JsonUtf8Reader.beginObject(JsonUtf8Reader.java:155)
    	at com.apollographql.apollo.compiler.parser.Schema$Companion.locateSchemaRootNode(Schema.kt:152)
    	at com.apollographql.apollo.compiler.parser.Schema$Companion.parse(Schema.kt:143)
    	... 100 more
    
    
    opened by GSala 4
  • The Web Version

    The Web Version

    Hey developers of CatchUp, Recently I was trying to build the web version of this app. I have tried building a basic webpage which currently supports just HACKERNEWS. I was wondering if we could combine both of the projects into one. We would have a web version(trying to shift to PWA since we can convert them to most platform supporting app) of this awesomely great android app.

    I have hosted the app HERE

    opened by Omkaragrawal 4
  • Default values support in moshkt

    Default values support in moshkt

    This implements an idea that Ryan and I were talking about, where we create a defaults-only instance first before then copying it with the potentially new values if they're present.

    Example code in Foo:

    @MoshiSerializable
    data class Foo(
        @Json(name = "first_name") val firstName: String,
        @Json(name = "last_name") val lastName: String,
        val age: Int,
        val nationalities: List<String> = emptyList(),
        val weight: Float,
        val tattoos: Boolean = false,
        val race: String?,
        val hasChildren: Boolean = false,
        val favoriteFood: String? = null,
        val favoriteDrink: String? = "Water"
    )
    

    Output:

    class Foo_JsonAdapter(private val moshi: Moshi) : JsonAdapter<Foo>() {
      override fun fromJson(reader: JsonReader): Foo? {
        if (reader.peek() == JsonReader.Token.NULL) {
          reader.nextNull<Any>()
        }
        lateinit var firstName: String
        lateinit var lastName: String
        var age = 0
        var nationalities: List<String>? = null
        var weight = 0.0f
        var tattoos: Boolean? = null
        var race: String? = null
        var hasChildren: Boolean? = null
        var favoriteFood: String? = null
        var favoriteDrink: String? = null
        reader.beginObject()
        while (reader.hasNext()) {
          when (reader.nextName()) {
            "first_name" -> firstName = moshi.adapter(String::class.java).fromJson(reader)!!
            "last_name" -> lastName = moshi.adapter(String::class.java).fromJson(reader)!!
            "age" -> age = moshi.adapter(Int::class.java).fromJson(reader)!!
            "nationalities" -> nationalities = moshi.adapter<List<String>>(Types.newParameterizedType(List::class.java, String::class.java)).fromJson(reader)!!
            "weight" -> weight = moshi.adapter(Float::class.java).fromJson(reader)!!
            "tattoos" -> tattoos = moshi.adapter(Boolean::class.java).fromJson(reader)!!
            "race" -> race = moshi.adapter(String::class.java).fromJson(reader)
            "hasChildren" -> hasChildren = moshi.adapter(Boolean::class.java).fromJson(reader)!!
            "favoriteFood" -> favoriteFood = moshi.adapter(String::class.java).fromJson(reader)
            "favoriteDrink" -> favoriteDrink = moshi.adapter(String::class.java).fromJson(reader)
            else -> reader.skipValue()
          }
        }
        reader.endObject()
        return Foo(firstName = firstName,
            lastName = lastName,
            age = age,
            weight = weight,
            race = race).let {
              it.copy(nationalities = nationalities ?: it.nationalities,
                  tattoos = tattoos ?: it.tattoos,
                  hasChildren = hasChildren ?: it.hasChildren,
                  favoriteFood = favoriteFood ?: it.favoriteFood,
                  favoriteDrink = favoriteDrink ?: it.favoriteDrink)
            }
      }
    
      override fun toJson(writer: JsonWriter, value: Foo?) {
        if (value == null) {
          writer.nullValue()
          return
        }
        writer.beginObject()
        writer.name("first_name")
        moshi.adapter(String::class.java).toJson(writer, value.firstName)
        writer.name("last_name")
        moshi.adapter(String::class.java).toJson(writer, value.lastName)
        writer.name("age")
        moshi.adapter(Int::class.java).toJson(writer, value.age)
        writer.name("nationalities")
        moshi.adapter<List<String>>(Types.newParameterizedType(List::class.java, String::class.java)).toJson(writer, value.nationalities)
        writer.name("weight")
        moshi.adapter(Float::class.java).toJson(writer, value.weight)
        writer.name("tattoos")
        moshi.adapter(Boolean::class.java).toJson(writer, value.tattoos)
        if (value.race != null) {
          writer.name("race")
          moshi.adapter(String::class.java).toJson(writer, value.race)
        }
        writer.name("hasChildren")
        moshi.adapter(Boolean::class.java).toJson(writer, value.hasChildren)
        if (value.favoriteFood != null) {
          writer.name("favoriteFood")
          moshi.adapter(String::class.java).toJson(writer, value.favoriteFood)
        }
        if (value.favoriteDrink != null) {
          writer.name("favoriteDrink")
          moshi.adapter(String::class.java).toJson(writer, value.favoriteDrink)
        }
        writer.endObject()
      }
    }
    
    opened by ZacSweers 4
  • Dependency Dashboard

    Dependency Dashboard

    This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.


    ⚠ Dependency Lookup Warnings ⚠

    • Renovate failed to look up the following dependencies: string:changelog_text, com.google.gson:gson.

    Files affected: app/build.gradle.kts, gradle/libs.versions.toml


    Ignored or Blocked

    These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

    • [ ] Update tikxml to v0.8.15 (com.tickaroo.tikxml:retrofit-converter, com.tickaroo.tikxml:converter-htmlescape, com.tickaroo.tikxml:core, com.tickaroo.tikxml:processor)

    Detected dependencies

    github-actions
    .github/workflows/ci.yml
    • actions/checkout v3
    • gradle/wrapper-validation-action v1
    • actions/setup-java v3
    • gradle/gradle-build-action v2
    • actions/upload-artifact v3
    gradle
    gradle.properties
    settings.gradle.kts
    • com.gradle.enterprise 3.12.2
    build.gradle.kts
    app/build.gradle.kts
    • string:changelog_text haha
    gradle/libs.versions.toml
    • com.uber.autodispose:autodispose 2.1.1
    • androidx.annotation:annotation 1.5.0
    • androidx.activity:activity 1.7.0-alpha02
    • androidx.activity:activity-compose 1.7.0-alpha02
    • androidx.appcompat:appcompat 1.7.0-alpha01
    • androidx.core:core 1.9.0
    • androidx.core:core-ktx 1.9.0
    • androidx.constraintlayout:constraintlayout 2.2.0-alpha05
    • androidx.browser:browser 1.5.0-alpha02
    • com.google.android.material:material 1.8.0-rc01
    • androidx.drawerlayout:drawerlayout 1.2.0-alpha01
    • androidx.emoji:emoji 1.2.0-alpha03
    • androidx.emoji:emoji-appcompat 1.2.0-alpha03
    • androidx.fragment:fragment 1.6.0-alpha04
    • androidx.fragment:fragment-ktx 1.6.0-alpha04
    • androidx.lifecycle:lifecycle-viewmodel 2.6.0-alpha03
    • androidx.lifecycle:lifecycle-viewmodel-ktx 2.6.0-alpha03
    • androidx.lifecycle:lifecycle-viewmodel-savedstate 2.6.0-alpha03
    • androidx.viewpager2:viewpager2 1.1.0-beta01
    • androidx.swiperefreshlayout:swiperefreshlayout 1.2.0-alpha01
    • androidx.palette:palette 1.0.0
    • androidx.palette:palette-ktx 1.0.0
    • androidx.preference:preference 1.2.0
    • androidx.preference:preference-ktx 1.2.0
    • androidx.recyclerview:recyclerview 1.2.1
    • androidx.lifecycle:lifecycle-compiler 2.6.0-alpha03
    • androidx.lifecycle:lifecycle-extensions 2.2.0
    • androidx.lifecycle:lifecycle-runtime-ktx 2.6.0-alpha03
    • androidx.room:room-compiler 2.5.0-rc01
    • androidx.room:room-ktx 2.5.0-rc01
    • androidx.room:room-runtime 2.5.0-rc01
    • androidx.room:room-rxjava3 2.5.0-rc01
    • androidx.room:room-paging 2.5.0-rc01
    • androidx.compose.animation:animation-graphics 1.4.0-alpha03
    • androidx.compose.ui:ui 1.4.0-alpha03
    • androidx.compose.ui:ui-tooling 1.4.0-alpha03
    • androidx.compose.foundation:foundation 1.4.0-alpha03
    • androidx.compose.ui:ui-text-google-fonts 1.3.2
    • androidx.compose.material:material 1.4.0-alpha03
    • androidx.compose.material:material-icons-core 1.4.0-alpha03
    • androidx.compose.material:material-icons-extended 1.4.0-alpha03
    • androidx.constraintlayout:constraintlayout-compose 1.1.0-alpha05
    • androidx.compose.runtime:runtime-livedata 1.4.0-alpha03
    • androidx.compose.runtime:runtime-rxjava3 1.4.0-alpha03
    • androidx.compose.runtime:runtime 1.4.0-alpha03
    • com.google.accompanist:accompanist-systemuicontroller 0.28.0
    • com.google.firebase:firebase-core 21.1.1
    • com.google.firebase:firebase-config 21.2.0
    • com.google.firebase:firebase-database 20.1.0
    • com.google.firebase:firebase-perf 20.3.0
    • com.squareup.anvil:annotations 2.4.3-1-8-0-RC
    • com.squareup.anvil:compiler 2.4.3-1-8-0-RC
    • com.apollographql.apollo3:apollo-http-cache 3.7.3
    • com.apollographql.apollo3:apollo-normalized-cache 3.7.3
    • com.apollographql.apollo3:apollo-runtime 3.7.3
    • com.google.auto:auto-common 1.2.1
    • com.google.auto.service:auto-service 1.0.1
    • com.uber.autodispose2:autodispose 2.1.1
    • com.uber.autodispose2:autodispose-android 2.1.1
    • com.uber.autodispose2:autodispose-androidx-lifecycle 2.1.1
    • com.uber.autodispose2:autodispose-lifecycle 2.1.1
    • com.android.tools:desugar_jdk_libs 2.0.0
    • com.squareup:javapoet 1.13.0
    • androidx.paging:paging-compose 1.0.0-alpha17
    • com.slack.circuit:circuit-core 0.5.0
    • com.slack.circuit:circuit-overlay 0.5.0
    • com.slack.circuit:circuit-retained 0.5.0
    • com.slack.circuit:circuit-codegen 0.5.0
    • com.slack.circuit:circuit-codegen-annotations 0.5.0
    • androidx.compose.material3:material3 1.1.0-alpha03
    • io.coil-kt:coil-base 2.2.2
    • io.coil-kt:coil 2.2.2
    • io.coil-kt:coil-gif 2.2.2
    • io.coil-kt:coil-compose 2.2.2
    • ru.ldralighieri.corbind:corbind 1.6.0
    • ru.ldralighieri.corbind:corbind-core 1.6.0
    • ru.ldralighieri.corbind:corbind-material 1.6.0
    • com.uber.crumb:crumb-annotations 0.1.0
    • com.uber.crumb:crumb-compiler 0.1.0
    • com.uber.crumb:crumb-compiler-api 0.1.0
    • com.google.dagger:dagger-compiler 2.44.2
    • com.google.dagger:dagger 2.44.2
    • com.google.dagger:dagger-spi 2.44.2
    • com.twitter.compose.rules:detekt 0.0.26
    • com.google.gson:gson 2.9.0
    • org.jetbrains.kotlinx:kotlinx-coroutines-core 1.6.4
    • org.jetbrains.kotlinx:kotlinx-coroutines-android 1.6.4
    • org.jetbrains.kotlinx:kotlinx-coroutines-rx3 1.6.4
    • org.jetbrains.kotlinx:kotlinx-datetime 0.4.0
    • org.jetbrains.kotlinx:kotlinx-metadata-jvm 0.5.0
    • com.squareup:kotlinpoet 1.12.0
    • io.noties.markwon:core 4.6.2
    • io.noties.markwon:ext-strikethrough 4.6.2
    • io.noties.markwon:ext-tables 4.6.2
    • io.noties.markwon:ext-tasklist 4.6.2
    • io.noties.markwon:html 4.6.2
    • io.noties.markwon:image 4.6.2
    • io.noties.markwon:image-coil 4.6.2
    • io.noties.markwon:linkify 4.6.2
    • io.noties.markwon:syntax-highlight 4.6.2
    • com.squareup.leakcanary:leakcanary-android 2.10
    • com.squareup.leakcanary:leakcanary-object-watcher-android 2.10
    • com.bugsnag:bugsnag-android 5.28.3
    • com.jakewharton.byteunits:byteunits 0.9.1
    • com.facebook.flipper:flipper 0.176.1
    • com.facebook.flipper:flipper-network-plugin 0.176.1
    • com.facebook.soloader:soloader 0.10.5
    • com.google.guava:guava 31.1-jre
    • com.jakewharton.madge:madge 1.1.4
    • com.jakewharton:process-phoenix 2.1.2
    • com.jakewharton.scalpel:scalpel 1.1.2
    • com.mattprecious.telescope:telescope 2.2.0
    • me.saket:flick 1.7.0
    • com.alexvasilkov:gesture-views 2.8.3
    • me.saket:inboxrecyclerview 3.0.0
    • org.glassfish:javax.annotation 10.0-b28
    • org.jsoup:jsoup 1.15.3
    • javax.annotation:jsr250-api 1.0
    • com.google.code.findbugs:jsr305 3.0.2
    • com.chibatching.kotpref:kotpref 2.13.2
    • com.chibatching.kotpref:enum-support 2.13.2
    • com.airbnb.android:lottie 5.2.0
    • com.serjltt.moshi:moshi-lazy-adapters 2.2
    • com.squareup.okio:okio 3.3.0
    • jp.wasabeef:recyclerview-animators 4.0.2
    • com.getkeepsafe.taptargetview:taptargetview 1.13.3
    • com.jakewharton.timber:timber 5.0.1
    • org.unbescape:unbescape 1.1.6.RELEASE
    • com.squareup.moshi:moshi-adapters 1.14.0
    • com.squareup.moshi:moshi 1.14.0
    • com.jakewharton.moshi:shimo 0.1.1
    • dev.zacsweers.moshix:moshi-sealed-runtime 0.21.0
    • com.squareup.okhttp3:okhttp-bom 5.0.0-alpha.11
    • com.squareup.okhttp3:okhttp 5.0.0-alpha.11
    • com.squareup.okhttp3:logging-interceptor 5.0.0-alpha.11
    • com.squareup.okhttp3:okhttp-ws 5.0.0-alpha.11
    • com.squareup.retrofit2:retrofit 2.9.0
    • com.squareup.retrofit2:retrofit-mock 2.9.0
    • com.squareup.retrofit2:converter-moshi 2.9.0
    • com.squareup.retrofit2:adapter-rxjava3 2.9.0
    • io.reactivex.rxjava3:rxandroid 3.0.2
    • com.uber.rxdogtag2:rxdogtag 2.0.1
    • com.uber.rxdogtag2:rxdogtag-autodispose 2.0.1
    • io.reactivex.rxjava3:rxjava 3.1.5
    • com.jakewharton.rxrelay3:rxrelay 3.0.1
    • com.tickaroo.tikxml:annotation 0.8.13
    • com.tickaroo.tikxml:processor 0.8.13
    • com.tickaroo.tikxml:core 0.8.13
    • com.tickaroo.tikxml:converter-htmlescape 0.8.13
    • com.tickaroo.tikxml:retrofit-converter 0.8.13
    • androidx.test.espresso:espresso-core 3.5.1
    • androidx.test.espresso:espresso-contrib 3.5.1
    • androidx.test.espresso:espresso-web 3.5.1
    • androidx.test:runner 1.5.2
    • androidx.test:rules 1.5.2
    • junit:junit 4.13.2
    • com.google.truth:truth 1.1.3
    • com.squareup.anvil 2.4.3-1-8-0-RC
    • com.android.application 8.0.0-alpha11
    • com.android.library 8.0.0-alpha11
    • com.apollographql.apollo3 3.7.3
    • com.bugsnag.android.gradle 7.4.0
    • org.gradle.android.cache-fix 2.6.1
    • io.gitlab.arturbosch.detekt 1.22.0
    • com.osacky.doctor 0.8.1
    • org.jetbrains.kotlin.jvm 1.8.0
    • org.jetbrains.kotlin.plugin.noarg 1.8.0
    • com.google.devtools.ksp 1.8.0-1.0.8
    • app.cash.licensee 1.6.0
    • dev.zacsweers.moshix 0.21.0
    • com.github.triplet.play 3.7.0
    • dev.zacsweers.redacted 1.3.0
    • org.gradle.test-retry 1.5.0
    • com.slack.gradle.base 0.4.0
    • com.slack.gradle.root 0.4.0
    • com.diffplug.spotless 6.12.1
    • com.github.ben-manes.versions 0.44.0
    libraries/appconfig/build.gradle.kts
    libraries/base-ui/build.gradle.kts
    libraries/compose-extensions/build.gradle.kts
    libraries/di/build.gradle.kts
    libraries/di/android/build.gradle.kts
    libraries/flowbinding/build.gradle.kts
    libraries/gemoji/build.gradle.kts
    libraries/kotlinutil/build.gradle.kts
    libraries/retrofitconverters/build.gradle.kts
    libraries/smmry/build.gradle.kts
    libraries/tooling/spi-multibinds-validator/build.gradle.kts
    libraries/tooling/spi-visualizer/build.gradle.kts
    libraries/util/build.gradle.kts
    platform/build.gradle.kts
    service-api/build.gradle.kts
    services/designernews/build.gradle.kts
    services/dribbble/build.gradle.kts
    services/github/build.gradle.kts
    services/hackernews/build.gradle.kts
    services/imgur/build.gradle.kts
    services/medium/build.gradle.kts
    services/newsapi/build.gradle.kts
    services/producthunt/build.gradle.kts
    services/reddit/build.gradle.kts
    services/slashdot/build.gradle.kts
    services/unsplash/build.gradle.kts
    services/uplabs/build.gradle.kts
    gradle-wrapper
    gradle/wrapper/gradle-wrapper.properties
    • gradle 8.0-rc-1

    • [ ] Check this box to trigger a request for Renovate to run again on this repository
    opened by renovate[bot] 0
  • Image viewer polish

    Image viewer polish

    • [ ] If in day mode, invert status bar icon colors back to previous activity's if past 50% transparency. In both dragging and dismissing
    • [x] load full res image with fade after transition. This is something Coil claims to be good at
    • [x] fix bottom icon and app bar UI. App bar casts a shadow and icon is too low
    • [x] ~update to new flick version and disable rotation when using shared element transitions~ Fix rotation on return transition
    • [x] Fix wrong AR in return transition image
    • [ ] enable bug reports on the image viewer activity
    • [x] faster transition. Like Google photos speed
    enhancement 
    opened by ZacSweers 0
  • Back arrow on order services is black in night mode

    Back arrow on order services is black in night mode

    Reported by @hzsweers

    App

    Version: 0.3.5-227-g5615cf5f-dev
    Version code: 1400
    

    Device details

    Make: Google
    Model: Pixel 3
    Resolution: 2028x1080
    Density: 440dpi (440)
    Release: 9
    API: 28
    

    Screenshot

    Logs

    No logs provided

    bug 
    opened by ZacSweers 0
Releases(0.3.2)
  • 0.3.2(Mar 25, 2018)

    • Enhancement: Hacker News stories only show the tag if it's not STORY, as almost all are STORY. Little less noisy
    • Fix: Crash due to rastered vector drawable pngs being used as vectors at runtime. This was a pretty gnarly issue and weird to track down, sorry for the trouble!
    • Misc: Goodbye to Dribbble for now, as their v1 API is being shut down this week and the v2 API only allows for content production and management rather than reading feeds.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Mar 19, 2018)

    • New: You can now reorder services in settings
    • New: You can now enable/disable services in settings. Note this is WIP and not polished yet.
    • Enhancement: GitHub is now paginated when there are more results (thanks to @charlesdurham!)
    • Enhancement: All models have been moved to native kotlin data classes using a new Moshi code gen implementation. Not really a user facing feature, but I'm really proud of it :)
    • Enhancement: APK size went on a diet! Fully enabled shrinking and APK splits, so now download size is ~4.9MB.
    • Fix: Medium is now fixed via pointing to the new /topic/popular endpoint
    • Fix: Building with a new version of D8 that should avoid some bizarre VM crashes on some Mediatek devices ಠ_ಠ
    Source code(tar.gz)
    Source code(zip)
  • 0.2.2(Dec 18, 2017)

  • 0.2.1(Dec 17, 2017)

  • 0.2.0(Dec 17, 2017)

    • New: Changelog notifications in the app
    • New: In-app hints implementation using TapTargetView
    • New: French translations (thanks to @anicolas!)
    • New: German translations (thanks to @AlexAmin!)
    • New: Built for Android 8.1
    • Enhancement: GitHub emojis are rendered in titles now (thanks to @charlesdurham!)
    • Enhancement: List items use ConstrainLayout now, which should have better perf (thanks to @R4md4c!)
    • Fix: Gifs in Dribbble should no longer accidentally show multiple times (thanks to @charlesdurham!)
    • Fix: Existing images shouldn't re-fade on refresh
    • Fix: A small memory leak in image services
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Oct 17, 2017)

    Few issues that have been immediately squashed

    • HackerNews sometimes sends junk items that are empty. Haven't seen that in a year of work before this, of course it happens the day I release
    • Accidental wrong java.time.Instant import instead of the one from threetenbp.
    Source code(tar.gz)
    Source code(zip)
Owner
Zac Sweers
Mobile @ Slack
Zac Sweers
This is a practice app. An app that you can find random recipes and choose the ones you like.

A food suggestion app like Tinder This is a practice app. In this app, you can find random recipes and choose the ones you like. This is main menu. Yo

Yunus Emre OCAK 4 May 25, 2022
To help to promote your android app by prompting users to rate your app in a bottom Sheet.

RateBottomSheet This an Android library to help to promote your Android App by prompting users to rate your app in the Google Play Store with a materi

Farham Hosseini 5 Jul 8, 2022
New style for app design Online Sunglasses Shop App UI made in Jetpack Compose.😉😎

JetSunglassUI-Android New style for app design Online Sunglasses Shop App UI made in Jetpack Compose. ?? ?? (Navigation Components, Dagger-Hilt, Mater

Arvind Meshram 18 Dec 12, 2022
A sample skeleton backend app built using Spring Boot kotlin, Expedia Kotlin Graphql, Reactive Web that can be deployed to Google App Engine Flexible environmennt

spring-kotlin-gql-gae This is a sample skeleton of a backend app that was built using: Spring Boot(Kotlin) Reactive Web Sprinng Data R2DBC with MYSQL

Dario Mungoi 7 Sep 17, 2022
These files are included in an Android Studio Project for a Magic the Gathering Life Counter app. The app was written in Kotlin.

Magic-Life-Counter These files were created in Android Studio using Kotlin. Usage This app was made to keep track of life totals while playing the tra

null 0 Dec 24, 2021
Relationship-app-android - An app with features aimed towards me and my girlfriend

RelationshipApp Android An Android app with features aimed towards me and my gir

Rostislav Osvald 0 Jan 3, 2022
Explore-KiiT-App - An app to simplify the complicated website navigation and keep track of Attendance

KiiT Explore App "An app to simplify the complicated website navigation and keep

Ajay Khatri 17 Oct 12, 2022
App with plant list 🌱 , the app reminds you when to water 💦 your best plant at a certain time.

Plant Life App with plant list ?? , the app reminds you when to water ?? your best plant at a certain time.. Table of Contents Introduction Features U

Haya Saud Alrawdhan 0 Jan 6, 2022
Swarup 2 Feb 6, 2022
Tictactoe-android-app - Simple TicTacToe Android app written in Kotlin

TicTacToe Android App This is a simple example of TicTacToe game as Android app

Blaž Čerpnjak 1 Jul 9, 2022
Android Note app that uses the "ktor-note-app" backend

KtorNoteApp Android Notes app that uses Ktor back end server Technologies employed: Kotlin MVVM Coroutines Custom REST API build with Ktor Responds to

Chris Athanas 2 Jul 25, 2022
Checks for app updates and automatically updates the current app if the new one in local storage have a different version

Silent Android App Update Sample This sample shows how to update Android app silently without user confirmation with a device owner app. It works on A

Hamdi Guerbej 1 May 14, 2022
Android app that shows what happened today in the history.

Today History Android app Master: Develop: Code Coverage: App that shows what happened today in history. Details Written in Kotlin. Android Studio 2.1

MakinGIANTS 29 Oct 3, 2022
🎶 Chromatic tuner app for Android

Chroma Chroma is a chromatic tuner, the perfect app to help you tune your musical instruments with precision and elegance. Features: Basic and complet

Adriel Café 76 Nov 30, 2022
This is a work-in-progress (🔧️) ultraviolet index viewer app for demonstrating Instant Apps + Kotlin + Dagger + MVP

UV Index A simple ultraviolet index viewer app for demonstrating: Instant Apps + Kotlin + Dagger + MVP Built With Weatherbit as weather API Android In

Mustafa Berkay Mutlu 65 Oct 31, 2022
Easy app for managing your files without ads, respecting your privacy & security

Simple File Manager Can also be used for browsing root files and SD card content. You can easily rename, copy, move, delete and share anything you wis

Simple Mobile Tools 1.2k Dec 29, 2022
🦁 A Disney app using transformation motions based on MVVM (ViewModel, Coroutines, Flow, LiveData, Room, Repository, Koin) architecture.

DisneyMotions A demo Disney app using transformation motions based on MVVM architecture. The motion system is included in the 1.2.0-alpha05 released m

Jaewoong Eum 1.4k Jan 2, 2023