Giter Site home page Giter Site logo

droidkaigi / conference-app-2018 Goto Github PK

View Code? Open in Web Editor NEW
1.3K 156.0 337.0 5.83 MB

The Official Conference App for DroidKaigi 2018 Tokyo

License: Apache License 2.0

Java 0.15% Kotlin 99.46% Ruby 0.39%
droidkaigi conference android-app android kotlin

conference-app-2018's Introduction

DroidKaigi 2018 official Android app

CircleCIWaffle.io - Columns and their card count

DroidKaigi 2018 is a conference tailored for developers on 8th and 9th February 2018.

Try it on your device via DeployGate

Features

  • View conference schedule and details of each session
  • Set notification for upcoming sessions on your preference
  • Search sessions and speakers and topics
  • Show Information Feed

Contributing

We are always welcome your contribution!

How to find the tasks

We use waffle.io to manage the tasks. Please find the issues you'd like to contribute in it. welcome contribute and easy are good for first contribution.

Of course, it would be great to send PullRequest which has no issue!

How to contribute

If you find the tasks you want to contribute, please comment in the issue like this to prevent to conflict contribution. We'll reply as soon as possible, but it's unnecessary to wait our reaction. It's okay to start contribution and send PullRequest!

We've designated these issues as good candidates for easy contribution. You can always fork the repository and send a pull request (on a branch other than master).

Development Environment

Kotlin

This app is full Kotlin!

RxJava2 & LiveData

Converting RxJava2's publisher to AAC LiveData with LiveDataReactiveStreams.

AllSessionsViewModel.kt

repository.sessions
    .toResult(schedulerProvider)
    .toLiveData()

LiveDataReactiveStreamsExt.kt

fun <T> Publisher<T>.toLiveData() = LiveDataReactiveStreams.fromPublisher(this)

Groupie

By using Groupie you can simplify the implementation around RecyclerView.

data class SpeakerItem(
        val speaker: Speaker
) : BindableItem<ItemSpeakerBinding>(speaker.id.hashCode().toLong()) {

    override fun bind(viewBinding: ItemSpeakerBinding, position: Int) {
        viewBinding.speaker = speaker
    }

    override fun getLayout(): Int = R.layout.item_speaker
}

Architecture

This app uses an Android Architecture Components(AAC) based architecture using AAC(LiveData, ViewModel, Room), Kotlin, RxJava, DataBinding, dependency injection, Firebase.

Fragment -> ViewModel

Use LifecycleObserver for telling lifecycle to ViewModel.

SessionsFragment.kt

class SessionsFragment : Fragment(), Injectable {

    private lateinit var sessionsViewModel: SessionsViewModel

...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        ...
        lifecycle.addObserver(sessionsViewModel)
        ...

SessionsViewModel.kt

class SessionsViewModel @Inject constructor(
        private val repository: SessionRepository,
        private val schedulerProvider: SchedulerProvider
) : ViewModel(), LifecycleObserver {
  ...
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate() {
    ...
}

ViewModel -> Repository

Use RxJava2(RxKotlin) and ViewModel#onCleared() for preventing leaking.

SessionsViewModel.kt

    private val compositeDisposable: CompositeDisposable = CompositeDisposable()

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate() {
        repository
                .refreshSessions()
                .subscribeBy(onError = defaultErrorHandler())
                .addTo(compositeDisposable)
    }

    override fun onCleared() {
        super.onCleared()
        compositeDisposable.clear()
    }

Repository -> API, Repository -> DB

Use Retrofit and save to the Architecture Component Room.

SessionDataRepository.kt

    override fun refreshSessions(): Completable {
        return api.getSessions()
                .doOnSuccess { response ->
                    sessionDatabase.save(response)
                }
                .subscribeOn(schedulerProvider.computation())
                .toCompletable()
    }

DB -> Repository

Use Room with RxJava2 Flowable Support. And SessionDataRepository holds Flowable property.

SessionDao.kt

    @Query("SELECT room_id, room_name FROM session GROUP BY room_id ORDER BY room_id")
    abstract fun getAllRoom(): Flowable<List<RoomEntity>>

SessionDataRepository.kt

class SessionDataRepository @Inject constructor(
        private val sessionDatabase: SessionDatabase,
...
) : SessionRepository {

    override val rooms: Flowable<List<Room>> =
            sessionDatabase.getAllRoom().toRooms()

Repository -> ViewModel

We create LiveData from a ReactiveStreams publisher with LiveDataReactiveStreams

SessionsViewModel.kt

    val rooms: LiveData<Result<List<Room>>> by lazy {
        repository.rooms
                .toResult(schedulerProvider)
                .toLiveData()
    }

LiveDataReactiveStreamsExt.kt

fun <T> Publisher<T>.toLiveData() = LiveDataReactiveStreams.fromPublisher(this) as LiveData<T>

And using Result class for error handling with Kotlin extension.

fun <T> Flowable<T>.toResult(schedulerProvider: SchedulerProvider): Flowable<Result<T>> =
        compose { item ->
            item
                    .map { Result.success(it) }
                    .onErrorReturn { e -> Result.failure(e.message ?: "unknown", e) }
                    .observeOn(schedulerProvider.ui())
                    .startWith(Result.inProgress())
        }
sealed class Result<T>(val inProgress: Boolean) {
    class InProgress<T> : Result<T>(true)
    data class Success<T>(var data: T) : Result<T>(false)
    data class Failure<T>(val errorMessage: String?, val e: Throwable) : Result<T>(false)

ViewModel -> Fragment

Fragment observe ViewModel's LiveData. We can use the result with Kotlin when expression. In is Result.Success block, you can access data with result.data by Kotlin Smart cast.

SessionsFragment.kt

        sessionsViewModel.rooms.observe(this, { result ->
            when (result) {
                is Result.InProgress -> {
                    binding.progress.show()
                }
                is Result.Success -> {
                    binding.progress.hide()
                    sessionsViewPagerAdapter.setRooms(result.data)
                }
                is Result.Failure -> {
                    Timber.e(result.e)
                    binding.progress.hide()
                }
            }
        })

Release

The release process is automated by using gradle-play-publisher. When we add git tag, CI deploys the release apk to GooglePlay alpha. To know more details, see .circleci/config.yml

elif [[ "${CIRCLE_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    echo "Deploy to Google Play"
    openssl aes-256-cbc -k $PUBLISHER_KEYS_JSON_DECRYPT_PASSWORD -d -in encrypted-publisher-keys.json -out app/publisher-keys.json
    ./gradlew publishApkRelease
fi

iOS App with Kotlin/Native and Kotlin Multiplatform Projects

Some contributors are challenging to develop iOS app with Kotlin/Native and Kotlin Multiplatform Projects.
We are watching this project. DroidKaigi2018iOS

DroidKaigi 2018 Flutter App

The unofficial conference app for DroidKaigi 2018 Tokyo https://github.com/konifar/droidkaigi2018-flutter

Thanks

Thank you for contributing!

Credit

This project uses some modern Android libraries and source codes.

License

Copyright 2018 DroidKaigi

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.

conference-app-2018's People

Contributors

amay077 avatar atsuko-fukui avatar atsuya046 avatar aya2453 avatar futabooo avatar gen0083 avatar hakutosuzuki avatar jmatsu avatar kaelaela avatar kakajika avatar katsutomu avatar keithyokoma avatar konifar avatar mhidaka avatar nacatl avatar nappannda avatar neonankiti avatar nukka123 avatar ogapants avatar panpanini avatar pluu avatar punchdrunker avatar rkowase avatar shikajiro avatar sho5nn avatar takahirom avatar tatsuhama avatar tebasakyu avatar ycrack avatar youta1119 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

conference-app-2018's Issues

Sessions are not shown

Overview (Required)

I'm not sure this is bug or not ๐Ÿค”
But on my device, the sessions are not shown for the first time.

Screenshot

Debug menu

Overview (Required)

  • It is useful!
  • I think that If we implement #60, I want to confirm by debug menu.

[Assigned]iOS app๐ŸŽ

Overview (Required)

  • We created a common module for iOS (and Server)
  • So, You can create iOS version.
  • I think that it is enough just to display the session list.

Links

[Assigned] Settings screen

Overview

This screen contains the following settings.

  • Enable Notification
  • Use Local time

We can do it with PreferenceFragmentCompat

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.