diff --git a/.gitignore b/.gitignore index ad0724f2..7e6a4a51 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,6 @@ .externalNativeBuild # not ignore -!.idea/codeStyleSettings.xml \ No newline at end of file +!.idea/codeStyleSettings.xml +!.idea/icon.png +!.idea/icon_dark.png diff --git a/.idea/icon.png b/.idea/icon.png new file mode 100755 index 00000000..fd3c3c16 Binary files /dev/null and b/.idea/icon.png differ diff --git a/.idea/icon_dark.png b/.idea/icon_dark.png new file mode 100755 index 00000000..fd3c3c16 Binary files /dev/null and b/.idea/icon_dark.png differ diff --git a/Dangerfile b/Dangerfile index 79cd516a..4c661fc0 100644 --- a/Dangerfile +++ b/Dangerfile @@ -5,3 +5,9 @@ github.dismiss_out_of_range_messages checkstyle_format.base_path = Dir.pwd checkstyle_format.report "app/build/reports/ktlint/ktlint-#{ENV['APP_BUILD_TYPE'].downcase}.xml" + +# AndroidLint +android_lint.report_file = "app/build/reports/lint-results-#{ENV['APP_BUILD_TYPE'].downcase}.xml" +android_lint.skip_gradle_task = true +android_lint.severity = "Error" +android_lint.lint(inline_mode: true) diff --git a/Gemfile b/Gemfile index bf0575bd..a0a7fc26 100644 --- a/Gemfile +++ b/Gemfile @@ -5,3 +5,4 @@ source "https://rubygems.org" gem "danger" gem "danger-checkstyle_format" +gem "danger-android_lint" diff --git a/Gemfile.lock b/Gemfile.lock index 9b6f49f2..40f571a3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,6 +3,8 @@ GEM specs: addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) + ansi (1.5.0) + ast (2.3.0) claide (1.0.2) claide-plugins (0.9.2) cork @@ -23,6 +25,9 @@ GEM no_proxy_fix octokit (~> 4.7) terminal-table (~> 1) + danger-android_lint (0.0.6) + danger-plugin-api (~> 1.0) + oga danger-checkstyle_format (0.1.1) danger-plugin-api (~> 1.0) ox (~> 2.0) @@ -39,9 +44,15 @@ GEM no_proxy_fix (0.1.2) octokit (4.8.0) sawyer (~> 0.8.0, >= 0.5.3) + oga (2.13) + ast + ruby-ll (~> 2.1) open4 (1.3.4) ox (2.8.2) public_suffix (3.0.1) + ruby-ll (2.1.2) + ansi + ast sawyer (0.8.1) addressable (>= 2.3.5, < 2.6) faraday (~> 0.8, < 1.0) @@ -54,6 +65,7 @@ PLATFORMS DEPENDENCIES danger + danger-android_lint danger-checkstyle_format BUNDLED WITH diff --git a/README.md b/README.md index 663a8999..0b36b6e2 100644 --- a/README.md +++ b/README.md @@ -245,6 +245,11 @@ SessionsFragment.kt }) ``` +## iOS App with Kotlin/Native and Kotlin Multiplatform Projects +Some contributors are challenging to develop iOS app with [Kotlin/Native](https://kotlinlang.org/docs/reference/native-overview.html) and [Kotlin Multiplatform Projects](https://kotlinlang.org/docs/reference/multiplatform.html). +We are watching this project. +[DroidKaigi2018iOS](https://github.com/kikuchy/DroidKaigi2018iOS) + ## Thanks Thank you for contributing! diff --git a/app/build.gradle b/app/build.gradle index abb1017d..40cd77f7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,16 +5,21 @@ apply plugin: "org.jlleitschuh.gradle.ktlint" apply plugin: 'io.fabric' apply plugin: 'com.github.ben-manes.versions' +// Manifest version +def versionMajor = 0 +def versionMinor = 1 +def versionPatch = 0 + android { - compileSdkVersion 27 + compileSdkVersion versions.compileSdk dataBinding.enabled = true defaultConfig { applicationId "io.github.droidkaigi.confsched2018" - minSdkVersion 19 - targetSdkVersion 27 - versionCode 1 - versionName "0.1" + minSdkVersion versions.minSdk + targetSdkVersion versions.targetSdk + versionCode versionMajor * 10000 + versionMinor * 100 + versionPatch + versionName "$versionMajor.$versionMinor.$versionPatch" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true multiDexEnabled true @@ -52,8 +57,17 @@ android { signingConfig signingConfigs.release debuggable false zipAlignEnabled true - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + minifyEnabled true + proguardFile getDefaultProguardFile('proguard-android.txt') + // global proguard settings + proguardFile file("proguard-rules.pro") + // library proguard settings + def files = rootProject.file("proguard") + .listFiles() + .findAll { it.name.startsWith("proguard") } + .toList() + .toArray() + proguardFiles(files) } } testOptions { @@ -66,112 +80,94 @@ android { } } +// See versions.gradle dependencies { - implementation project(':model') // Kotlin - implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" - - // Retrofit - def retrofitVersion = '2.3.0' - implementation "com.squareup.retrofit2:retrofit:$retrofitVersion" - implementation "com.squareup.retrofit2:converter-moshi:$retrofitVersion" - implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofitVersion" - - // Kotshi - def kotshiVersion = '0.3.0-beta1' - implementation "se.ansman.kotshi:api:$kotshiVersion" - kapt "se.ansman.kotshi:compiler:$kotshiVersion" - - // Android Architecture Components - implementation 'android.arch.lifecycle:runtime:1.0.3' - implementation 'android.arch.lifecycle:extensions:1.0.0' - implementation 'android.arch.lifecycle:reactivestreams:1.0.0' - implementation 'android.arch.persistence.room:runtime:1.0.0' - implementation "android.arch.persistence.room:rxjava2:1.0.0" - kapt 'android.arch.persistence.room:compiler:1.0.0' - - // RxJava - implementation "io.reactivex.rxjava2:rxjava:2.1.8" - implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' - implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0' - - // OkHttp - implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1' - - // Support Library - def supportLibraryVersion = '27.0.2' - implementation "com.android.support:support-v4:$supportLibraryVersion" - implementation "com.android.support:appcompat-v7:$supportLibraryVersion" - implementation "com.android.support:design:$supportLibraryVersion" - implementation "com.android.support:support-vector-drawable:$supportLibraryVersion" - implementation "com.android.support:cardview-v7:$supportLibraryVersion" - implementation "com.android.support:customtabs:$supportLibraryVersion" - implementation 'com.android.support.constraint:constraint-layout:1.1.0-beta4' - - // DataBinding - kapt "com.android.databinding:compiler:3.0.1" - - // Dagger - def daggerVersion = '2.13' - implementation "com.google.dagger:dagger:$daggerVersion" - implementation "com.google.dagger:dagger-android:$daggerVersion" - implementation "com.google.dagger:dagger-android-support:$daggerVersion" - kapt "com.google.dagger:dagger-compiler:$daggerVersion" - kapt "com.google.dagger:dagger-android-processor:$daggerVersion" - - // Firebase - // Adjust version for emulator - def firebaseVersion = '11.6.2' - implementation "com.google.firebase:firebase-firestore:$firebaseVersion" - implementation "com.google.firebase:firebase-auth:$firebaseVersion" - implementation "com.google.firebase:firebase-core:$firebaseVersion" - implementation('com.crashlytics.sdk.android:crashlytics:2.7.1@aar') { - transitive = true - } + implementation depends.kotlin.stdlib + + //==================== Support Library ==================== + implementation depends.support.v4 + implementation depends.support.appcompat + implementation depends.support.design + implementation depends.support.cardview + implementation depends.support.customtabs + implementation depends.support.constraint + implementation depends.support.multidex + + //==================== Network ==================== + implementation depends.okhttp3.loggingIntercepter + + implementation depends.retrofit.core + implementation depends.retrofit.converterMoshi + implementation depends.retrofit.adapterRxJava2 + + //==================== Structure ==================== + implementation depends.kotshi.api + kapt depends.kotshi.compiler + + implementation depends.lifecycle.runtime + implementation depends.lifecycle.extensions + implementation depends.lifecycle.reactivestreams + implementation depends.room.runtime + implementation depends.room.rxjava2 + kapt depends.room.compiler + + implementation depends.rxjava2.core + implementation depends.rxjava2.android + implementation depends.rxjava2.kotlin - // ThreeTenABP for JSR-310 backport - implementation 'com.jakewharton.threetenabp:threetenabp:1.0.5' - testImplementation 'org.threeten:threetenbp:1.3.3' + kapt depends.binding.compiler - // groupie for RecyclerView Adapter - def groupieVersion = '2.0.0' - implementation "com.xwray:groupie-databinding:$groupieVersion" - implementation "com.xwray:groupie:$groupieVersion" + implementation depends.dagger.core + implementation depends.dagger.android + implementation depends.dagger.androidSupport + kapt depends.dagger.compiler + kapt depends.dagger.androidProcessor + + implementation depends.firebase.firestore + implementation depends.firebase.auth + implementation depends.firebase.core + + implementation depends.threetenabp + + //==================== UI ==================== + implementation depends.glide.core + implementation depends.glide.okhttp3 + kapt depends.glide.compiler + + implementation depends.groupie.core + implementation depends.groupie.binding + + implementation depends.downloadableCalligraphy + + //==================== Debug ==================== + debugImplementation depends.stetho.core + debugImplementation depends.stetho.okhttp3 + + implementation(depends.crashlytics) { + transitive = true + } - // MultiDex - implementation 'com.android.support:multidex:1.0.2' + implementation depends.timber - // Glide - def glideVersion = '4.4.0' - implementation "com.github.bumptech.glide:glide:$glideVersion" - implementation "com.github.bumptech.glide:okhttp3-integration:$glideVersion" - kapt "com.github.bumptech.glide:compiler:$glideVersion" + debugImplementation depends.leakcanary - // Timber - implementation 'com.jakewharton.timber:timber:4.6.0' + debugImplementation depends.debot.core + releaseImplementation depends.debot.noop - // Downloadable Calligraphy - implementation 'com.github.takahirom.downloadable.calligraphy:downloadable-calligraphy:0.1.2' + //==================== Test ==================== + testImplementation depends.junit + testImplementation depends.mockitoKotlin - // LeakCanary - debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4' + testImplementation depends.robolectric.core + testImplementation depends.assertk - // Stetho - def stethoVersion = '1.5.0' - debugImplementation "com.facebook.stetho:stetho:$stethoVersion" - debugImplementation "com.facebook.stetho:stetho-okhttp3:$stethoVersion" + testImplementation depends.threetenbp - // Test - testImplementation 'junit:junit:4.12' - testImplementation "com.nhaarman:mockito-kotlin:1.5.0" - // Unit Test - testImplementation "org.robolectric:robolectric:3.5.1" - testImplementation 'com.willowtreeapps.assertk:assertk:0.9' - // Instrumentation Test - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + androidTestImplementation depends.supporttest.runner + androidTestImplementation depends.supporttest.espresso } @@ -180,7 +176,7 @@ repositories { } ktlint { - version = "0.14.0" + version = versions.ktlint android = true reporter = "checkstyle" ignoreFailures = true diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index f1b42451..90a44c4e 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -19,3 +19,10 @@ # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile + +# Keep the names of our models so that Moshi can use them +-keepnames class io.github.droidkaigi.confsched2018.data.api.response.** { *; } + +# Keep SourceFile names & Line Numbers for stack traces. (Note: If we are really security concious, +# we should remove this line. +-keepattributes SourceFile,LineNumberTable diff --git a/app/src/debug/java/io/github/droidkaigi/confsched2018/presentation/DebotObserver.kt b/app/src/debug/java/io/github/droidkaigi/confsched2018/presentation/DebotObserver.kt new file mode 100644 index 00000000..87c63983 --- /dev/null +++ b/app/src/debug/java/io/github/droidkaigi/confsched2018/presentation/DebotObserver.kt @@ -0,0 +1,44 @@ +package io.github.droidkaigi.confsched2018.presentation + +import android.app.Activity +import android.app.Application +import android.os.Bundle +import android.support.v4.app.FragmentActivity +import com.tomoima.debot.Debot + +class DebotObserver : Application.ActivityLifecycleCallbacks { + + val debot: Debot by lazy { + Debot.getInstance() + } + + override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) { + if (activity !is Activity) return + debot.allowShake(activity.applicationContext) + } + + override fun onActivityStarted(activity: Activity?) { + // no-op + } + + override fun onActivityResumed(activity: Activity?) { + if (activity !is FragmentActivity) return + debot.startSensor(activity) + } + + override fun onActivityPaused(activity: Activity?) { + debot.stopSensor() + } + + override fun onActivityStopped(activity: Activity?) { + // no-op + } + + override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) { + // no-op + } + + override fun onActivityDestroyed(activity: Activity?) { + // no-op + } +} diff --git a/app/src/debug/java/io/github/droidkaigi/confsched2018/presentation/DebugApp.kt b/app/src/debug/java/io/github/droidkaigi/confsched2018/presentation/DebugApp.kt index 89f5ea24..48b0e8e4 100644 --- a/app/src/debug/java/io/github/droidkaigi/confsched2018/presentation/DebugApp.kt +++ b/app/src/debug/java/io/github/droidkaigi/confsched2018/presentation/DebugApp.kt @@ -2,6 +2,7 @@ package io.github.droidkaigi.confsched2018.presentation import com.facebook.stetho.Stetho import com.squareup.leakcanary.LeakCanary +import com.tomoima.debot.DebotConfigurator import timber.log.Timber class DebugApp : App() { @@ -11,6 +12,7 @@ class DebugApp : App() { setupTimber() setupLeakCanary() setupStetho() + setupDebot() } private fun setupTimber() { @@ -24,4 +26,9 @@ class DebugApp : App() { private fun setupStetho() { Stetho.initializeWithDefaults(this) } + + private fun setupDebot() { + DebotConfigurator.configureWithDefault() + registerActivityLifecycleCallbacks(DebotObserver()) + } } diff --git a/app/src/debug/res/mipmap-hdpi/ic_launcher.png b/app/src/debug/res/mipmap-hdpi/ic_launcher.png new file mode 100755 index 00000000..674f0597 Binary files /dev/null and b/app/src/debug/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/debug/res/mipmap-mdpi/ic_launcher.png b/app/src/debug/res/mipmap-mdpi/ic_launcher.png new file mode 100755 index 00000000..37dea020 Binary files /dev/null and b/app/src/debug/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/debug/res/mipmap-xhdpi/ic_launcher.png b/app/src/debug/res/mipmap-xhdpi/ic_launcher.png new file mode 100755 index 00000000..ef9d1105 Binary files /dev/null and b/app/src/debug/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/debug/res/mipmap-xxhdpi/ic_launcher.png b/app/src/debug/res/mipmap-xxhdpi/ic_launcher.png new file mode 100755 index 00000000..08bbbbb3 Binary files /dev/null and b/app/src/debug/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100755 index 00000000..4c7463c5 Binary files /dev/null and b/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/data/api/response/mapper/SessionDataMapperExt.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/data/api/response/mapper/SessionDataMapperExt.kt index 8b1958f5..c8e098e4 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/data/api/response/mapper/SessionDataMapperExt.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/data/api/response/mapper/SessionDataMapperExt.kt @@ -17,7 +17,7 @@ fun List?.toSessionSpeakerJoinEntities(): List responseSession.speakers!!.forEach { speakerId -> sessionSpeakerJoinEntity += - SessionSpeakerJoinEntity(responseSession.id!!, speakerId!!) + SessionSpeakerJoinEntity(responseSession.id, speakerId!!) } } return sessionSpeakerJoinEntity diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/data/repository/SessionDataRepository.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/data/repository/SessionDataRepository.kt index dae3785d..27809377 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/data/repository/SessionDataRepository.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/data/repository/SessionDataRepository.kt @@ -32,6 +32,7 @@ class SessionDataRepository @Inject constructor( override val rooms: Flowable> = sessionDatabase.getAllRoom().toRooms() + .filter { it.isNotEmpty() } override val topics: Flowable> = sessionDatabase.getAllTopic().toTopics() override val sessions: Flowable> = diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/di/TopicDetailActivityBuilder.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/di/TopicDetailActivityBuilder.kt index 60c658f1..c362f052 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/di/TopicDetailActivityBuilder.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/di/TopicDetailActivityBuilder.kt @@ -12,4 +12,4 @@ import io.github.droidkaigi.confsched2018.presentation.topic.TopicDetailActivity ] ) abstract fun contributeTopicDetailActivity(): TopicDetailActivity -} \ No newline at end of file +} diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/di/TopicDetailActivityModule.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/di/TopicDetailActivityModule.kt index 7f8c6b52..c6cd08a7 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/di/TopicDetailActivityModule.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/di/TopicDetailActivityModule.kt @@ -8,4 +8,4 @@ import io.github.droidkaigi.confsched2018.presentation.topic.TopicDetailActivity @Module interface TopicDetailActivityModule { @Binds fun providesAppCompatActivity(activity: TopicDetailActivity): AppCompatActivity -} \ No newline at end of file +} diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/FragmentBindingAdapters.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/FragmentBindingAdapters.kt index a1056ff4..efe45261 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/FragmentBindingAdapters.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/FragmentBindingAdapters.kt @@ -12,8 +12,8 @@ class FragmentBindingAdapters @Inject constructor(internal val fragment: Fragment) { @BindingAdapter( value = [ - "bind:loadImage", - "bind:placeHolder", + "loadImage", + "placeHolder", "android:layout_width", "android:layout_height" ] diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/ImageBinding.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/ImageBinding.kt index 43df41b4..a17ca496 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/ImageBinding.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/ImageBinding.kt @@ -10,11 +10,11 @@ import android.widget.ImageView @BindingMethods( BindingMethod(type = ImageView::class, - attribute = "app:srcCompat", + attribute = "srcCompat", method = "setImageDrawable")) class ImageBinding -@BindingAdapter("bind:colorTint", "app:srcCompat") +@BindingAdapter("colorTint", "srcCompat") fun ImageView.setColorTint(@ColorInt color: Int, drawable: Drawable) { val wrappedDrawable = DrawableCompat.wrap(drawable.mutate()) DrawableCompat.setTint(wrappedDrawable, color) diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/TextBinding.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/TextBinding.kt index 51fbdf03..fbb6522f 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/TextBinding.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/binding/TextBinding.kt @@ -14,7 +14,7 @@ import io.github.droidkaigi.confsched2018.model.toReadableDateTimeString import io.github.droidkaigi.confsched2018.model.toReadableTimeString import java.util.regex.Pattern -@BindingAdapter(value = ["bind:dayNumber"]) +@BindingAdapter(value = ["dayNumber"]) fun TextView.setDayText(dayNumber: Int) { text = context.getString( R.string.session_day_title, @@ -22,7 +22,7 @@ fun TextView.setDayText(dayNumber: Int) { ) } -@BindingAdapter(value = ["bind:startDate", "bind:endDate"]) +@BindingAdapter(value = ["startDate", "endDate"]) fun TextView.setPeriodText(startDate: Date?, endDate: Date?) { startDate ?: return endDate ?: return @@ -33,7 +33,7 @@ fun TextView.setPeriodText(startDate: Date?, endDate: Date?) { ) } -@BindingAdapter(value = ["bind:prefix", "bind:roomName"]) +@BindingAdapter(value = ["prefix", "roomName"]) fun TextView.setRoomText(prefix: String?, roomName: String?) { prefix ?: return text = when (roomName) { null -> "" @@ -47,7 +47,7 @@ fun TextView.setDateText(date: Date?) { text = date.toReadableDateTimeString() } -@BindingAdapter(value = ["bind:highlightText"]) +@BindingAdapter(value = ["highlightText"]) fun TextView.setHighlightText(highlightText: String?) { // By toString, clear highlight text. val stringBuilder = SpannableStringBuilder(text.toString()) diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/menu/DrawerMenu.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/menu/DrawerMenu.kt index b4f93835..e85403c9 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/menu/DrawerMenu.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/menu/DrawerMenu.kt @@ -42,7 +42,7 @@ class DrawerMenu @Inject constructor( drawerLayout.addDrawerListener(it) }.apply { isDrawerIndicatorEnabled = true - isDrawerSlideAnimationEnabled = true + isDrawerSlideAnimationEnabled = false syncState() } } diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/view/SpeakersSummaryLayout.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/view/SpeakersSummaryLayout.kt index 3adcadd8..b38504e4 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/view/SpeakersSummaryLayout.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/common/view/SpeakersSummaryLayout.kt @@ -86,12 +86,14 @@ class SpeakersSummaryLayout @JvmOverloads constructor( * app:speakers="@{speakers}" * /> */ - fun setSpeakers(speakers: List) { - speakerList.clear() - speakerList.addAll(speakers) + fun setSpeakers(speakers: List?) { + speakers?.let { + speakerList.clear() + speakerList.addAll(speakers) - updateIcons() - updateText() + updateIcons() + updateText() + } } private fun updateIcons() { diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsActivity.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsActivity.kt index d202327a..c6d7e2d0 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsActivity.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsActivity.kt @@ -35,6 +35,13 @@ class ContributorsActivity : BaseActivity(), HasSupportFragmentInjector { setSupportActionBar(binding.toolbar) supportActionBar?.setDisplayHomeAsUpEnabled(true) navigationController.navigateToContributor() + drawerMenu.setup(binding.toolbar, binding.drawerLayout, binding.drawer) + } + + override fun onBackPressed() { + if (drawerMenu.closeDrawerIfNeeded()) { + super.onBackPressed() + } } companion object { diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsFragment.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsFragment.kt index 7b5fb7f1..96f12457 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsFragment.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsFragment.kt @@ -7,6 +7,7 @@ import android.os.Bundle import android.support.customtabs.CustomTabsIntent import android.support.v4.app.Fragment import android.support.v4.content.ContextCompat +import android.support.v4.widget.SwipeRefreshLayout import android.support.v7.widget.SimpleItemAnimator import android.view.LayoutInflater import android.view.View @@ -19,7 +20,6 @@ import io.github.droidkaigi.confsched2018.di.Injectable import io.github.droidkaigi.confsched2018.presentation.NavigationController import io.github.droidkaigi.confsched2018.presentation.Result import io.github.droidkaigi.confsched2018.presentation.common.binding.FragmentDataBindingComponent -import io.github.droidkaigi.confsched2018.presentation.contributor.item.ContributorHeaderItem import io.github.droidkaigi.confsched2018.presentation.contributor.item.ContributorItem import io.github.droidkaigi.confsched2018.presentation.contributor.item.ContributorsSection import io.github.droidkaigi.confsched2018.util.ext.observe @@ -47,13 +47,11 @@ class ContributorsFragment : Fragment(), Injectable { super.onActivityCreated(savedInstanceState) setupRecyclerView() + setupSwipeRefresh() contributorsViewModel.contributors.observe(this, { result -> when (result) { is Result.Success -> { val contributors = result.data - val header = - ContributorHeaderItem(contributors.size, fragmentDataBindingComponent) - contributorSection.setHeader(header) contributorSection.updateContributors(contributors) } is Result.Failure -> { @@ -86,6 +84,16 @@ class ContributorsFragment : Fragment(), Injectable { } } + private fun setupSwipeRefresh() { + binding.contributorsSwipeRefresh.setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener { + contributorsViewModel.onRefreshContributors() + + if (binding.contributorsSwipeRefresh.isRefreshing()) { + binding.contributorsSwipeRefresh.setRefreshing(false) + } + }) + } + companion object { fun newInstance(): ContributorsFragment = ContributorsFragment() } diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsViewModel.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsViewModel.kt index 6432a7f2..4d56744e 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsViewModel.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/ContributorsViewModel.kt @@ -32,6 +32,14 @@ class ContributorsViewModel @Inject constructor( @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { + refreshContributors() + } + + fun onRefreshContributors() { + refreshContributors() + } + + private fun refreshContributors() { repository.loadContributors() .subscribeBy(onError = defaultErrorHandler()) .addTo(compositeDisposable) diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorHeaderItem.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorHeaderItem.kt index c0b73f4a..a33c4661 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorHeaderItem.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorHeaderItem.kt @@ -2,6 +2,7 @@ package io.github.droidkaigi.confsched2018.presentation.contributor.item import android.databinding.DataBindingUtil import android.view.View +import com.xwray.groupie.Item import com.xwray.groupie.databinding.BindableItem import com.xwray.groupie.databinding.ViewHolder import io.github.droidkaigi.confsched2018.R @@ -22,4 +23,12 @@ class ContributorHeaderItem( override fun bind(viewBinding: ItemContributorHeaderBinding, position: Int) { viewBinding.contributorCount = contributorCount } + + override fun isSameAs(other: Item<*>?): Boolean = + other is ContributorHeaderItem + + override fun equals(other: Any?): Boolean = + contributorCount == (other as? ContributorHeaderItem?)?.contributorCount + + override fun hashCode(): Int = contributorCount } diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorItem.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorItem.kt index f39dd177..7061d47c 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorItem.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorItem.kt @@ -12,7 +12,7 @@ import io.github.droidkaigi.confsched2018.presentation.common.binding.FragmentDa data class ContributorItem( val contributor: Contributor, private val dataBindingComponent: FragmentDataBindingComponent -) : BindableItem() { +) : BindableItem(contributor.name.hashCode().toLong()) { override fun createViewHolder(itemView: View): ViewHolder { return ViewHolder(DataBindingUtil.bind(itemView, dataBindingComponent)) diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorsSection.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorsSection.kt index 69650951..f6e4721c 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorsSection.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/contributor/item/ContributorsSection.kt @@ -9,7 +9,8 @@ class ContributorsSection( private val dataBindingComponent: FragmentDataBindingComponent ) : Section() { fun updateContributors(topics: List) { - val list = mutableListOf>() + val header = ContributorHeaderItem(topics.size, dataBindingComponent) + val list = mutableListOf>(header) topics.sortedByDescending { it.contributions }.mapTo(list) { ContributorItem(it, dataBindingComponent) } diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/detail/SessionDetailActivity.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/detail/SessionDetailActivity.kt index 87b07ba9..fe54cfe0 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/detail/SessionDetailActivity.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/detail/SessionDetailActivity.kt @@ -85,7 +85,6 @@ class SessionDetailActivity : } } - override fun supportFragmentInjector(): AndroidInjector = dispatchingAndroidInjector override fun onBackPressed() { diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/favorite/FavoriteSessionsFragment.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/favorite/FavoriteSessionsFragment.kt index 77c8bc6d..94f7b2fd 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/favorite/FavoriteSessionsFragment.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/favorite/FavoriteSessionsFragment.kt @@ -36,7 +36,7 @@ class FavoriteSessionsFragment : Fragment(), Injectable { private lateinit var binding: FragmentFavoriteSessionsBinding - private val sessionsSection = DateSessionsSection(this) + private val sessionsSection = DateSessionsSection() @Inject lateinit var navigationController: NavigationController @Inject lateinit var viewModelFactory: ViewModelProvider.Factory diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/feed/FeedFragment.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/feed/FeedFragment.kt index 31febf11..76399270 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/feed/FeedFragment.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/feed/FeedFragment.kt @@ -66,14 +66,17 @@ class FeedFragment : Fragment(), Injectable { is Result.Success -> { val posts = result.data val inflater = TransitionInflater.from(context) - val expandTransition = inflater.inflateTransition(R.transition.expand_toggle) + val expandTransition = inflater.inflateTransition(R.transition.feed_item_expand) + val collapseTransition = + inflater.inflateTransition(R.transition.feed_item_collapse) postsSection.update(posts .map { FeedItem( it, feedItemCollapsed, feedItemExpanded, - expandTransition + expandTransition, + collapseTransition ) }) } diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/feed/item/FeedItem.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/feed/item/FeedItem.kt index b42bf1ad..728848fe 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/feed/item/FeedItem.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/feed/item/FeedItem.kt @@ -2,7 +2,10 @@ package io.github.droidkaigi.confsched2018.presentation.feed.item import android.support.constraint.ConstraintSet import android.support.transition.Transition +import android.support.transition.TransitionListenerAdapter import android.support.transition.TransitionManager +import android.support.v7.widget.RecyclerView +import android.view.View import com.xwray.groupie.databinding.BindableItem import io.github.droidkaigi.confsched2018.R import io.github.droidkaigi.confsched2018.databinding.ItemFeedBinding @@ -13,18 +16,27 @@ data class FeedItem( private val feedItemCollapsed: ConstraintSet, private val feedItemExpanded: ConstraintSet, private val expandTransition: Transition, + private val collapseTransition: Transition, private var expanded: Boolean = false ) : BindableItem( post.hashCode().toLong() ) { + private val touchIgnorer = View.OnTouchListener { _, _ -> true } override fun bind(viewBinding: ItemFeedBinding, position: Int) { viewBinding.post = post viewBinding.root.setOnClickListener { + val parent = viewBinding.root.parent as RecyclerView + parent.setOnTouchListener(touchIgnorer) + val transition = (if (expanded) collapseTransition else expandTransition).clone() + + transition.addListener(object : TransitionListenerAdapter() { + override fun onTransitionEnd(transition: Transition) { + parent.setOnTouchListener(null) + } + }) + TransitionManager.beginDelayedTransition(parent, transition) expanded = !expanded - // FIXME: Animation!! - TransitionManager - .beginDelayedTransition(viewBinding.feedItemConstraintLayout, expandTransition) if (!expanded) { feedItemCollapsed.applyTo(viewBinding.feedItemConstraintLayout) } else { diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/SearchFragment.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/SearchFragment.kt index e8e5b7c6..50196b41 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/SearchFragment.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/SearchFragment.kt @@ -8,6 +8,7 @@ import android.support.annotation.StringRes import android.support.v4.app.Fragment import android.support.v4.app.FragmentManager import android.support.v4.app.FragmentStatePagerAdapter +import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.SearchView import android.support.v7.widget.SimpleItemAnimator import android.view.LayoutInflater @@ -33,6 +34,7 @@ import io.github.droidkaigi.confsched2018.util.SessionAlarm import io.github.droidkaigi.confsched2018.util.ext.color import io.github.droidkaigi.confsched2018.util.ext.eachChildView import io.github.droidkaigi.confsched2018.util.ext.observe +import io.github.droidkaigi.confsched2018.util.ext.setLinearDivider import io.github.droidkaigi.confsched2018.util.ext.toGone import io.github.droidkaigi.confsched2018.util.ext.toVisible import timber.log.Timber @@ -43,7 +45,7 @@ class SearchFragment : Fragment(), Injectable { @Inject lateinit var viewModelFactory: ViewModelProvider.Factory @Inject lateinit var navigationController: NavigationController - private val sessionsSection = SimpleSessionsSection(this) + private val sessionsSection = SimpleSessionsSection() private val speakersSection = SearchSpeakersSection(FragmentDataBindingComponent(this)) private val searchViewModel: SearchViewModel by lazy { @@ -125,6 +127,8 @@ class SearchFragment : Fragment(), Injectable { binding.sessionsRecycler.apply { adapter = groupAdapter (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false + setLinearDivider(R.drawable.shape_divider_vertical_6dp, + layoutManager as LinearLayoutManager) } } diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/SearchTopicsFragment.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/SearchTopicsFragment.kt index df49799b..cca7ccd9 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/SearchTopicsFragment.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/SearchTopicsFragment.kt @@ -62,7 +62,7 @@ class SearchTopicsFragment : Fragment(), Injectable { private fun setupRecyclerView() { val groupAdapter = GroupAdapter().apply { - setOnItemClickListener {item, _ -> + setOnItemClickListener { item, _ -> val topicItem = item as? TopicItem ?: return@setOnItemClickListener navigationController.navigateToTopicDetailActivity(topicItem.topic.id) } diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/item/TopicItem.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/item/TopicItem.kt index 9c1fd8ff..8edc76e9 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/item/TopicItem.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/item/TopicItem.kt @@ -32,4 +32,4 @@ data class TopicItem( } override fun getLayout(): Int = R.layout.item_topic -} \ No newline at end of file +} diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/item/TopicsGroup.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/item/TopicsGroup.kt index 7c483993..e1e0e04a 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/item/TopicsGroup.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/search/item/TopicsGroup.kt @@ -14,4 +14,4 @@ class TopicsGroup(val dataBindingComponent: FragmentDataBindingComponent) : Sect } update(list) } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/AllSessionsFragment.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/AllSessionsFragment.kt index 07fe2cf2..e08d8dca 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/AllSessionsFragment.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/AllSessionsFragment.kt @@ -37,7 +37,7 @@ class AllSessionsFragment : Fragment(), Injectable { private lateinit var binding: FragmentAllSessionsBinding - private val sessionsSection = DateSessionsSection(this) + private val sessionsSection = DateSessionsSection() @Inject lateinit var viewModelFactory: ViewModelProvider.Factory @Inject lateinit var navigationController: NavigationController diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/RoomSessionsFragment.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/RoomSessionsFragment.kt index 19cdf548..54aa824a 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/RoomSessionsFragment.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/RoomSessionsFragment.kt @@ -39,7 +39,7 @@ class RoomSessionsFragment : Fragment(), Injectable { private lateinit var binding: FragmentRoomSessionsBinding private lateinit var roomName: String - private val sessionsSection = DateSessionsSection(this) + private val sessionsSection = DateSessionsSection() @Inject lateinit var navigationController: NavigationController diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/DateSessionsSection.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/DateSessionsSection.kt index cd6eb783..a8bf002a 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/DateSessionsSection.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/DateSessionsSection.kt @@ -1,6 +1,5 @@ package io.github.droidkaigi.confsched2018.presentation.sessions.item -import android.support.v4.app.Fragment import com.xwray.groupie.Item import com.xwray.groupie.Section import io.github.droidkaigi.confsched2018.model.Session @@ -8,7 +7,7 @@ import io.github.droidkaigi.confsched2018.model.toReadableDateString import io.github.droidkaigi.confsched2018.model.toReadableTimeString import java.util.SortedMap -class DateSessionsSection(private val fragment: Fragment) : Section() { +class DateSessionsSection : Section() { fun updateSessions( sessions: List, onFavoriteClickListener: (Session.SpeechSession) -> Unit, @@ -19,7 +18,7 @@ class DateSessionsSection(private val fragment: Fragment) : Section() { is Session.SpeechSession -> { @Suppress("USELESS_CAST") SpeechSessionItem( - it, onFavoriteClickListener, fragment, simplify) as SessionItem + it, onFavoriteClickListener, simplify) as SessionItem } is Session.SpecialSession -> { @Suppress("USELESS_CAST") diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/SimpleSessionsSection.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/SimpleSessionsSection.kt index 59e25e20..051fec70 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/SimpleSessionsSection.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/SimpleSessionsSection.kt @@ -1,11 +1,10 @@ package io.github.droidkaigi.confsched2018.presentation.sessions.item -import android.support.v4.app.Fragment import com.xwray.groupie.Item import com.xwray.groupie.Section import io.github.droidkaigi.confsched2018.model.Session -class SimpleSessionsSection(val fragment: Fragment) : Section() { +class SimpleSessionsSection : Section() { fun updateSessions( sessions: List, onFavoriteClickListener: (Session.SpeechSession) -> Unit, @@ -18,7 +17,6 @@ class SimpleSessionsSection(val fragment: Fragment) : Section() { SpeechSessionItem( it, onFavoriteClickListener, - fragment, true, searchQuery ) as Item<*> diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/SpeechSessionItem.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/SpeechSessionItem.kt index 6f5dae30..72d71991 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/SpeechSessionItem.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/sessions/item/SpeechSessionItem.kt @@ -1,6 +1,5 @@ package io.github.droidkaigi.confsched2018.presentation.sessions.item -import android.support.v4.app.Fragment import com.xwray.groupie.databinding.BindableItem import io.github.droidkaigi.confsched2018.R import io.github.droidkaigi.confsched2018.databinding.ItemSpeechSessionBinding @@ -10,7 +9,6 @@ import io.github.droidkaigi.confsched2018.util.lang data class SpeechSessionItem( override val session: Session.SpeechSession, private val onFavoriteClickListener: (Session.SpeechSession) -> Unit, - private val fragment: Fragment, private val isShowDayNumber: Boolean = false, private val searchQuery: String = "", private val simplify: Boolean = false diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/speaker/SpeakerDetailFragment.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/speaker/SpeakerDetailFragment.kt index 141a26a6..8f1ed317 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/speaker/SpeakerDetailFragment.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/speaker/SpeakerDetailFragment.kt @@ -29,7 +29,7 @@ class SpeakerDetailFragment : Fragment(), Injectable { private lateinit var binding: FragmentSpeakerDetailBinding @Inject lateinit var viewModelFactory: ViewModelProvider.Factory - private val sessionsSection = SimpleSessionsSection(this) + private val sessionsSection = SimpleSessionsSection() @Inject lateinit var navigationController: NavigationController private val speakerDetailViewModel: SpeakerDetailViewModel by lazy { diff --git a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/topic/TopicDetailFragment.kt b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/topic/TopicDetailFragment.kt index 4e67f0f9..d9a6fa27 100644 --- a/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/topic/TopicDetailFragment.kt +++ b/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/topic/TopicDetailFragment.kt @@ -25,14 +25,13 @@ import io.github.droidkaigi.confsched2018.util.ext.setLinearDivider import timber.log.Timber import javax.inject.Inject - class TopicDetailFragment : Fragment(), Injectable { @Inject lateinit var navigationController: NavigationController @Inject lateinit var viewModelFactory: ViewModelProvider.Factory private lateinit var binding: FragmentTopicDetailBinding - private val sessionsSection = SimpleSessionsSection(this) + private val sessionsSection = SimpleSessionsSection() private val topicDetailViewModel: TopicDetailViewModel by lazy { ViewModelProviders.of(activity!!, viewModelFactory).get(TopicDetailViewModel::class.java) @@ -85,7 +84,7 @@ class TopicDetailFragment : Fragment(), Injectable { val linearLayoutManager = LinearLayoutManager(context) binding.sessionsRecycler.apply { adapter = groupAdapter - setLinearDivider(R.drawable.shape_divider_vertical_6dp, linearLayoutManager) + setLinearDivider(R.drawable.shape_divider_vertical_12dp, linearLayoutManager) } } diff --git a/app/src/main/res/drawable/shape_divider_vertical_12dp.xml b/app/src/main/res/drawable/shape_divider_vertical_12dp.xml new file mode 100644 index 00000000..7b342241 --- /dev/null +++ b/app/src/main/res/drawable/shape_divider_vertical_12dp.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/layout/activity_contributor.xml b/app/src/main/res/layout/activity_contributor.xml index 1b4876bd..5365ac51 100644 --- a/app/src/main/res/layout/activity_contributor.xml +++ b/app/src/main/res/layout/activity_contributor.xml @@ -4,32 +4,48 @@ xmlns:tools="http://schemas.android.com/tools" tools:context="io.github.droidkaigi.confsched2018.presentation.contributor.ContributorsActivity" > - - - + android:layout_height="match_parent" + > + + + + + - - + diff --git a/app/src/main/res/layout/activity_topic_detail.xml b/app/src/main/res/layout/activity_topic_detail.xml index c4b1b17f..e11d63fd 100644 --- a/app/src/main/res/layout/activity_topic_detail.xml +++ b/app/src/main/res/layout/activity_topic_detail.xml @@ -54,41 +54,41 @@ diff --git a/app/src/main/res/layout/fragment_contributor.xml b/app/src/main/res/layout/fragment_contributor.xml index 4bcbfdee..35d3dc72 100644 --- a/app/src/main/res/layout/fragment_contributor.xml +++ b/app/src/main/res/layout/fragment_contributor.xml @@ -4,17 +4,25 @@ xmlns:tools="http://schemas.android.com/tools" > - + > + + + + diff --git a/app/src/main/res/layout/fragment_favorite_sessions.xml b/app/src/main/res/layout/fragment_favorite_sessions.xml index 45d6e818..e62ae069 100644 --- a/app/src/main/res/layout/fragment_favorite_sessions.xml +++ b/app/src/main/res/layout/fragment_favorite_sessions.xml @@ -53,11 +53,11 @@ /> diff --git a/app/src/main/res/layout/item_contributor_header.xml b/app/src/main/res/layout/item_contributor_header.xml index 3bbe81ac..c9bd5a20 100644 --- a/app/src/main/res/layout/item_contributor_header.xml +++ b/app/src/main/res/layout/item_contributor_header.xml @@ -1,7 +1,7 @@ diff --git a/app/src/main/res/layout/item_date_header.xml b/app/src/main/res/layout/item_date_header.xml index 099f3347..0e959db4 100644 --- a/app/src/main/res/layout/item_date_header.xml +++ b/app/src/main/res/layout/item_date_header.xml @@ -15,16 +15,16 @@ diff --git a/app/src/main/res/layout/item_feed.xml b/app/src/main/res/layout/item_feed.xml index f8986e49..f5f7ebc2 100644 --- a/app/src/main/res/layout/item_feed.xml +++ b/app/src/main/res/layout/item_feed.xml @@ -16,18 +16,19 @@ > + /> diff --git a/app/src/main/res/layout/item_speaker.xml b/app/src/main/res/layout/item_speaker.xml index e84bf82f..0055ac7d 100644 --- a/app/src/main/res/layout/item_speaker.xml +++ b/app/src/main/res/layout/item_speaker.xml @@ -35,11 +35,11 @@ /> diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png index 806d3e63..0f1b41ba 100755 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png index fd3c3c16..4b019978 100755 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png index d6ddf97b..4be4adc6 100755 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 54a0da6a..97c98f2f 100755 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index f5fdb212..b069c183 100755 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/transition/feed_item_collapse.xml b/app/src/main/res/transition/feed_item_collapse.xml new file mode 100644 index 00000000..4a7f2021 --- /dev/null +++ b/app/src/main/res/transition/feed_item_collapse.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/transition/expand_toggle.xml b/app/src/main/res/transition/feed_item_expand.xml similarity index 80% rename from app/src/main/res/transition/expand_toggle.xml rename to app/src/main/res/transition/feed_item_expand.xml index 671653c8..2a139525 100644 --- a/app/src/main/res/transition/expand_toggle.xml +++ b/app/src/main/res/transition/feed_item_expand.xml @@ -12,23 +12,27 @@ the License. --> - + + + + + + - + + - diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index f8989ece..f1c43ee2 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -64,8 +64,10 @@ コントリビューター - %d 人のコントリビューター コントリビューターのプロフィール画像 + + %d 人のコントリビューター + %1$s がもうすぐ始まります。 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 13bc9b7a..57ab666a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -61,14 +61,18 @@ + %d session %d session %d sessions Contributors - %d Contributors contributors avatar + + %d Contributor + %d Contributors + %1$s will start soon diff --git a/app/src/main/res/values/text_apperance.xml b/app/src/main/res/values/text_apperance.xml index cc095353..ddd3e090 100644 --- a/app/src/main/res/values/text_apperance.xml +++ b/app/src/main/res/values/text_apperance.xml @@ -30,4 +30,57 @@ 13sp @font/notosans_regular + + + + + + + + + + + + + + + + + + + + diff --git a/build.gradle b/build.gradle index f104fd11..c902a671 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,5 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - buildscript { - ext.kotlin_version = '1.2.10' + apply from: "${rootDir.absolutePath}/versions.gradle" repositories { google() @@ -10,12 +8,12 @@ buildscript { maven { url 'https://maven.fabric.io/public' } } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.gms:google-services:3.1.0' - classpath "gradle.plugin.org.jlleitschuh.gradle:ktlint-gradle:3.0.0" - classpath 'io.fabric.tools:gradle:1.25.1' - classpath 'com.github.ben-manes:gradle-versions-plugin:0.17.0' + classpath "com.android.tools.build:gradle:$versions.gradleBuildTool" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin" + classpath "com.google.gms:google-services:$versions.googleServices" + classpath "gradle.plugin.org.jlleitschuh.gradle:ktlint-gradle:$versions.ktlintGradle" + classpath "io.fabric.tools:gradle:$versions.fabricGradleTool" + classpath "com.github.ben-manes:gradle-versions-plugin:$versions.gradleVersions" } } diff --git a/gradle.properties b/gradle.properties index aac7c9b4..854793c6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,3 +15,4 @@ org.gradle.jvmargs=-Xmx1536m # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true +org.gradle.caching=true diff --git a/model/build.gradle b/model/build.gradle index d1825e27..7f8d92a9 100644 --- a/model/build.gradle +++ b/model/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'kotlin' dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$versions.kotlin" } sourceCompatibility = "1.7" diff --git a/model/src/main/java/io/github/droidkaigi/confsched2018/model/Contributor.kt b/model/src/main/java/io/github/droidkaigi/confsched2018/model/Contributor.kt index e8d2e3a1..c4d88e6f 100644 --- a/model/src/main/java/io/github/droidkaigi/confsched2018/model/Contributor.kt +++ b/model/src/main/java/io/github/droidkaigi/confsched2018/model/Contributor.kt @@ -2,9 +2,9 @@ package io.github.droidkaigi.confsched2018.model data class Contributor( val name: String, - var bio: String?, - var avatarUrl: String, - var htmlUrl: String, - var contributions: Int + val bio: String?, + val avatarUrl: String, + val htmlUrl: String, + val contributions: Int ) diff --git a/model/src/main/java/io/github/droidkaigi/confsched2018/model/Room.kt b/model/src/main/java/io/github/droidkaigi/confsched2018/model/Room.kt index 249eef88..10cc18f8 100644 --- a/model/src/main/java/io/github/droidkaigi/confsched2018/model/Room.kt +++ b/model/src/main/java/io/github/droidkaigi/confsched2018/model/Room.kt @@ -2,5 +2,5 @@ package io.github.droidkaigi.confsched2018.model data class Room( val id: Int, - var name: String + val name: String ) diff --git a/model/src/main/java/io/github/droidkaigi/confsched2018/model/Session.kt b/model/src/main/java/io/github/droidkaigi/confsched2018/model/Session.kt index da053880..3f960bff 100644 --- a/model/src/main/java/io/github/droidkaigi/confsched2018/model/Session.kt +++ b/model/src/main/java/io/github/droidkaigi/confsched2018/model/Session.kt @@ -1,34 +1,34 @@ package io.github.droidkaigi.confsched2018.model sealed class Session( - open var id: String, - open var dayNumber: Int, - open var startTime: Date, - open var endTime: Date + open val id: String, + open val dayNumber: Int, + open val startTime: Date, + open val endTime: Date ) { data class SpeechSession( - override var id: String, - override var dayNumber: Int, - override var startTime: Date, - override var endTime: Date, - var title: String, - var desc: String, - var room: Room, - var format: String, - var language: String, - var topic: Topic, - var level: Level, + override val id: String, + override val dayNumber: Int, + override val startTime: Date, + override val endTime: Date, + val title: String, + val desc: String, + val room: Room, + val format: String, + val language: String, + val topic: Topic, + val level: Level, var isFavorited: Boolean, - var speakers: List + val speakers: List ) : Session(id, dayNumber, startTime, endTime) data class SpecialSession( - override var id: String, - override var dayNumber: Int, - override var startTime: Date, - override var endTime: Date, - var title: Int, - var room: Room? + override val id: String, + override val dayNumber: Int, + override val startTime: Date, + override val endTime: Date, + val title: Int, + val room: Room? ) : Session(id, dayNumber, startTime, endTime) } diff --git a/model/src/main/java/io/github/droidkaigi/confsched2018/model/Speaker.kt b/model/src/main/java/io/github/droidkaigi/confsched2018/model/Speaker.kt index 59a7eb41..52243e5f 100644 --- a/model/src/main/java/io/github/droidkaigi/confsched2018/model/Speaker.kt +++ b/model/src/main/java/io/github/droidkaigi/confsched2018/model/Speaker.kt @@ -2,11 +2,11 @@ package io.github.droidkaigi.confsched2018.model data class Speaker( val id: String, - var name: String, - var tagLine: String, - var imageUrl: String, - var twitterUrl: String?, - var githubUrl: String?, - var blogUrl: String?, - var companyUrl: String? + val name: String, + val tagLine: String, + val imageUrl: String, + val twitterUrl: String?, + val githubUrl: String?, + val blogUrl: String?, + val companyUrl: String? ) diff --git a/proguard/proguard-glide.pro b/proguard/proguard-glide.pro new file mode 100644 index 00000000..77572f23 --- /dev/null +++ b/proguard/proguard-glide.pro @@ -0,0 +1,9 @@ +# Glide specific rules # +# https://github.com/bumptech/glide + +-keep public class * implements com.bumptech.glide.module.GlideModule +-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { + **[] $VALUES; + public *; +} + diff --git a/proguard/proguard-google-dagger2.pro b/proguard/proguard-google-dagger2.pro new file mode 100644 index 00000000..90cfcff1 --- /dev/null +++ b/proguard/proguard-google-dagger2.pro @@ -0,0 +1 @@ +-dontwarn com.google.errorprone.annotations.* diff --git a/proguard/proguard-moshi.pro b/proguard/proguard-moshi.pro new file mode 100644 index 00000000..cbd087d5 --- /dev/null +++ b/proguard/proguard-moshi.pro @@ -0,0 +1,7 @@ +-dontwarn okio.** +-dontwarn javax.annotation.** +-keepclasseswithmembers class * { + @com.squareup.moshi.* ; +} +-keep @com.squareup.moshi.JsonQualifier interface * + diff --git a/proguard/proguard-square-okhttp3.pro b/proguard/proguard-square-okhttp3.pro new file mode 100644 index 00000000..0b7eb396 --- /dev/null +++ b/proguard/proguard-square-okhttp3.pro @@ -0,0 +1,5 @@ +-dontwarn okhttp3.** +-dontwarn okio.** +-dontwarn javax.annotation.** +# A resource is loaded with a relative path so the package of this class must be preserved. +-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase diff --git a/proguard/proguard-square-okio.pro b/proguard/proguard-square-okio.pro new file mode 100644 index 00000000..bd8d34b9 --- /dev/null +++ b/proguard/proguard-square-okio.pro @@ -0,0 +1,3 @@ +# Okio +-dontnote retrofit2.Platform +-dontwarn retrofit2.Platform$Java8 diff --git a/proguard/proguard-square-retrofit2.pro b/proguard/proguard-square-retrofit2.pro new file mode 100644 index 00000000..8aef37b0 --- /dev/null +++ b/proguard/proguard-square-retrofit2.pro @@ -0,0 +1,2 @@ +-dontwarn okio.** +-dontwarn javax.annotation.** diff --git a/proguard/proguard-support-design.pro b/proguard/proguard-support-design.pro new file mode 100644 index 00000000..92b99cca --- /dev/null +++ b/proguard/proguard-support-design.pro @@ -0,0 +1,9 @@ +# Support Design library +# We use reflection to change these, so we need to keep them. + +-keepclassmembers class android.support.design.internal.BottomNavigationMenuView { + private boolean mShiftingMode; +} +-keepclassmembers class android.support.design.internal.BottomNavigationItemView { + private int mDefaultMargin; +} diff --git a/proguard/proguard-support-v7.pro b/proguard/proguard-support-v7.pro new file mode 100644 index 00000000..7dea737d --- /dev/null +++ b/proguard/proguard-support-v7.pro @@ -0,0 +1,3 @@ +# Support library + +-keep class android.support.v7.widget.SearchView { *; } diff --git a/versions.gradle b/versions.gradle new file mode 100644 index 00000000..da38859f --- /dev/null +++ b/versions.gradle @@ -0,0 +1,127 @@ +ext { + versions = [ + compileSdk : 27, + buildTools : "26.0.1", + minSdk : 19, + targetSdk : 27, + gradleBuildTool : "3.0.1", + kotlin : "1.2.10", + googleServices : "3.1.1", + ktlint : "0.14.0", + ktlintGradle : "3.0.0", + fabricGradleTool: "1.25.1", + gradleVersions : "0.17.0", + supportLibrary : "27.0.2", + retrofit : "2.3.0", + kotshi : "0.3.0-beta1", + arch : "1.0.0", + dagger : "2.13", + firebase : "11.6.2", // Adjust version for emulator + glide : "4.4.0", + groupie : "2.0.2", + stetho : "1.5.0", + debot : "2.0.3", + ] + + depends = [ + kotlin : [ + stdlib: "org.jetbrains.kotlin:kotlin-stdlib-jre7:$versions.kotlin", + ], + + //==================== Support Library ==================== + support : [ + v4 : "com.android.support:support-v4:$versions.supportLibrary", + appcompat : "com.android.support:appcompat-v7:$versions.supportLibrary", + design : "com.android.support:design:$versions.supportLibrary", + cardview : "com.android.support:cardview-v7:$versions.supportLibrary", + customtabs: "com.android.support:customtabs:$versions.supportLibrary", + constraint: "com.android.support.constraint:constraint-layout:1.1.0-beta4", + multidex : "com.android.support:multidex:1.0.2", + ], + + //==================== Network ==================== + okhttp3 : [ + loggingIntercepter: "com.squareup.okhttp3:logging-interceptor:3.9.1" + ], + retrofit : [ + core : "com.squareup.retrofit2:retrofit:$versions.retrofit", + converterMoshi: "com.squareup.retrofit2:converter-moshi:$versions.retrofit", + adapterRxJava2: "com.squareup.retrofit2:adapter-rxjava2:$versions.retrofit", + ], + + //==================== Structure ==================== + kotshi : [ + api : "se.ansman.kotshi:api:$versions.kotshi", + compiler: "se.ansman.kotshi:compiler:$versions.kotshi", + ], + lifecycle : [ + runtime : "android.arch.lifecycle:runtime:$versions.arch", + extensions : "android.arch.lifecycle:extensions:$versions.arch", + reactivestreams: "android.arch.lifecycle:reactivestreams:$versions.arch", + ], + room : [ + runtime : "android.arch.persistence.room:runtime:$versions.arch", + rxjava2 : "android.arch.persistence.room:rxjava2:$versions.arch", + compiler: "android.arch.persistence.room:compiler:$versions.arch", + ], + rxjava2 : [ + core : "io.reactivex.rxjava2:rxjava:2.1.8", + android: "io.reactivex.rxjava2:rxandroid:2.0.1", + kotlin : "io.reactivex.rxjava2:rxkotlin:2.2.0", + ], + binding : [ + compiler: "com.android.databinding:compiler:3.0.1", + ], + dagger : [ + core : "com.google.dagger:dagger:$versions.dagger", + compiler : "com.google.dagger:dagger-compiler:$versions.dagger", + android : "com.google.dagger:dagger-android:$versions.dagger", + androidSupport : "com.google.dagger:dagger-android-support:$versions.dagger", + androidProcessor: "com.google.dagger:dagger-android-processor:$versions.dagger", + ], + firebase : [ + firestore: "com.google.firebase:firebase-firestore:$versions.firebase", + auth : "com.google.firebase:firebase-auth:$versions.firebase", + core : "com.google.firebase:firebase-core:$versions.firebase", + ], + threetenabp : "com.jakewharton.threetenabp:threetenabp:1.0.5", + + //==================== UI ==================== + glide : [ + core : "com.github.bumptech.glide:glide:$versions.glide", + okhttp3 : "com.github.bumptech.glide:okhttp3-integration:$versions.glide", + compiler: "com.github.bumptech.glide:compiler:$versions.glide", + ], + groupie : [ + core : "com.xwray:groupie:$versions.groupie", + binding: "com.xwray:groupie-databinding:$versions.groupie", + ], + downloadableCalligraphy: "com.github.takahirom.downloadable.calligraphy:downloadable-calligraphy:0.1.2", + + //==================== Debug ==================== + stetho : [ + core : "com.facebook.stetho:stetho:$versions.stetho", + okhttp3: "com.facebook.stetho:stetho-okhttp3:$versions.stetho", + ], + crashlytics : "com.crashlytics.sdk.android:crashlytics:2.7.1@aar", + timber : "com.jakewharton.timber:timber:4.6.0", + leakcanary : "com.squareup.leakcanary:leakcanary-android:1.5.4", + debot : [ + core: "com.tomoima.debot:debot:$versions.debot", + noop: "com.tomoima.debot:debot-no-op:$versions.debot", + ], + + //==================== Test ==================== + junit : "junit:junit:4.12", + mockitoKotlin : "com.nhaarman:mockito-kotlin:1.5.0", + robolectric : [ + core: "org.robolectric:robolectric:3.5.1", + ], + assertk : "com.willowtreeapps.assertk:assertk:0.9", + threetenbp : "org.threeten:threetenbp:1.3.3", + supporttest : [ + runner : "com.android.support.test:runner:1.0.1", + espresso: "com.android.support.test.espresso:espresso-core:3.0.1" + ], + ] +}