Giter VIP home page Giter VIP logo

interscheckin's People

Contributors

private-yusuke avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

kasatomorning

interscheckin's Issues

deep link で venue ID を受け取ってチェックインできるようにする

概要

日常生活の中で特定の Venueに立ち入るときがあるとき、そのチェックインをするために画面操作をすることすら面倒に感じることがある。そこで、deep link で Venue の ID を受け取りつつアプリを立ち上げ、そのリンクを辿るだけで自動的にチェックインできるようにしたい。

想定するユースケースは、NFC タグに deep link が発火するような URI を書き込んでおいて、頻繁に訪れる場所にそれを貼り付けておき、そこに自分が来たらスマホをかざすだけでチェックインできるようにする、というものが挙げられる。

必要な実装

  • deep link
    • AndroidManifest.xml 内で deep link を使用するための定義を追加する
      • MainActivity に対応するタグの中に <intent-filter> を追加する
      • interscheckin:// で始まる URI を対象にしたい
  • InterscheckinNavigations.kt

自動的に定期的な位置情報の更新を実施する

概要

現在の実装では Venue のリストの更新を待ってからチェックインをすることになっている。Venue リストの更新で最も時間を必要とするのは最大で数秒程度かかる位置情報の取得であり、良好なインターネットへの接続があるときには API レスポンスの取得は 1 秒もかからず終了している。これによってチェックインの機会を逃すことが無視できない程度に発生している。

そこで、位置情報の取得については一定時間ごとに実施できるような実装を追加する。これは、定期的な位置情報の取得をすると、一回限りの位置情報取得よりも安定して短時間に新しい位置情報を得られる特性があるためである。
また、その間隔をユーザーが設定できるようにする。

必要な実装

位置情報の取得頻度について

定期的に位置情報を見る必要があり、間隔はユーザーが設定できるようにしたい。
プリセットとして以下のような値が指定されているとよさそう。

  • 高頻度
    • 間隔:1 秒
  • 通常
    • 間隔:3 秒
  • 低頻度
    • 間隔:10 秒

間隔のカスタマイズ機能は必要だと思ったときに開発すればよい。

取得頻度の設定

#114 が実現できたら「位置情報」の欄から定期的に位置情報を取得するのを切り替えるためのスイッチと、それが有効なときに取得頻度の設定ができるようにする。

MainScreen の実装

定期的な位置情報の取得が有効になっている場合にはそのプリセット設定に従って定期的に位置情報を取得するようにする。

位置情報の取得のためには昔に実装されていた以下の関数を復活させるとよさそう。

@SuppressLint("MissingPermission")
fun FusedLocationProviderClient.locationFlow(
locationRequest: LocationRequest
) = callbackFlow<Location> {
val callback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
super.onLocationResult(locationResult)
for (location in locationResult.locations) {
Log.d(LOG_TAG, "Sending location $location")
trySend(location)
}
}
}
Log.d(LOG_TAG, "requestLocationUpdates")
requestLocationUpdates(
locationRequest,
callback,
Looper.getMainLooper()
)
awaitClose {
Log.d(LOG_TAG, "Removing location update callback")
removeLocationUpdates(callback)
}
}

高頻度な位置情報の更新であっても Foursquare の API rate limit には引っ掛からないし1、普段遣いしていても毎月貰える $ 200 分のクレジットのうち $ 2 も使えていないので問題はないと考える。困ったらそのときに対応策を練る(定期的な位置情報の更新時には API を利用せずにローカルのキャッシュのみを用いるようにする、など)。

Footnotes

  1. https://location.foursquare.com/developer/reference/rate-limits

`build.gradle` を `build.gradle.kts` に移行する

概要

今後 build.gradle.kts に移行したい。
Originally posted by @private-yusuke in #66 (comment)

利点

#66 で行ったようなマニュアルな差分を以下のようにまとめられるようになる(かも)。

kotlin {
    jvmToolchain {
        (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(17))
    }
}

また、IDE の補完が効きやすくなりそう。

やること

関連リンク

Navigation Compose 周辺のリファクタリングをする

概要

Navigation Compose 関連のコードが MainActivity に集約されており、若干汚くなっているので分離する。

やること

  • sealed class InterscheckinScreens を定義する。このクラスを継承する object はコンストラクタで name: stringnavArguments: List<NamedNavArgument> を受け取る
  • @Composable 関数 InterscheckinNavigations を作成し、現状 NavHost に渡している箇所を切り出す
  • @Composable 関数 InterscheckinNavHost を作成し、その中に NavHost を書いている箇所を切り出す
  • @Composable 関数 InterscheckinMain を作成し、その中に InterscheckinNavHost を置く
    • これを MainActivitysetContent 内で呼ぶ

`HistoriesScreen` のページネーションがうまく動いていない

概要

#34 で追加した HistoriesScreen のページネーションがおかしくなっている。具体的には、すでにリストに入っているチェックイン履歴が後の append 処理で追加されているように見える。

原因

FoursquareClientImpl から CheckinApiService を利用する際に limit の値が伝播していなかった。また、CheckinApiService.getCheckinHistories にて limit 引数を用意していなかった。

github.com の Actions ランナー `macos-12` で走る Instrumented test が flaky である

概要

この部分の job が確率的に落ちることがある。手動でリトライすると通ることがあるが、煩雑である。
具体的な処理としては x86-64 な Android のエミュレータが QEMU で走っており、instrumented test 自体が開始されるまでに 15 分程度の時間がかかる。確率的に落ちるのは、このテストの実行中に発生するものであり、特段理由を吐かずに死ぬケースもあったと記憶している。

解決案

https://circleci.com/ja/product/features/resource-classes/ を見ていると無料で 4 CPU, 16 GB RAM な Arm VM を使わせてくれるらしい。これを使ったら安定稼動かつテスト時間が半分ぐらいになったりしないかなと気になっている。

あるいは、github.com が arm64 な runner を提供しはじめてくれると非常に助かる(他力本願)。

Venues list を更新中にチェックインしようとするとアプリが落ちる

概要

Venues list の更新をしている最中に、Venue を長押しすることによるチェックインを行うとアプリが異常終了する。

stacktrace

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: pub.yusuke.interscheckin, PID: 26525
    java.lang.ClassCastException: pub.yusuke.interscheckin.ui.main.MainContract$LocationState$Loading cannot be cast to pub.yusuke.interscheckin.ui.main.MainContract$LocationState$Loaded
        at pub.yusuke.interscheckin.ui.main.MainViewModel.checkIn(MainViewModel.kt:109)
        at pub.yusuke.interscheckin.ui.main.MainScreenKt$MainScreen$1$1$1$2$1.invokeSuspend(MainScreen.kt:98)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
        at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
        at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
        at android.os.Handler.handleCallback(Handler.java:942)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7898)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
    	Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.ui.platform.MotionDurationScaleImpl@f3ac0ce, androidx.compose.runtime.BroadcastFrameClock@170bef, StandaloneCoroutine{Cancelling}@94d16fc, AndroidUiDispatcher@5bbc185]

原因箇所

/*
* LocationState.Loaded になってから Venue が設定され、その後この関数が呼び出されるので、
* ここの型キャストは安全であると考える
*/
val loadedState = locationState.value as MainContract.LocationState.Loaded

全然安全じゃなかった件について

修正方法

LocationState.Loading のときには lastLocation が格納されていることが期待されるので、それを取り出すようにすればよいと考える。この State は lastLocation が null のときは起動直後で位置情報を受け取ったことがない扱いとしているようだが、素直に InitialLoading のような状態を新たに用意してここの null 許容をやめるようにしても良いと思う。

友達選択画面を作る

概要

root issue: #183

Foursquare の API を利用して友達一覧を取得し、それを表示する画面を実装する。
「API を叩いて画面を表示する」という点では #34 でも同じことをしているので、参考になるかもしれません。

実装するもの

API リクエスト部分

:library:foursquareclientpub.yusuke.foursquareclient.network 以下に FriendApiService を作成し、友達一覧を取得する API を呼び出すためのメソッドを持つ interface を定義する。
ページネーションの処理も入れてください。
TODO: 具体的な API エンドポイントやページネーション用のパラメータを書く

画面

以下のものを表示してください。

  • 上部に TopAppBar があり、左上に「戻る」ボタンがあること
  • 友達のアイコンと名前、そして hometown を表示する行が並んでいること
    • #34 のスクリーンショットのように
    • @Preview を用いて適当なユーザーを一行だけ表示したときの見た目が確認できるようになっているとベター

また、MainScreen からこの画面に遷移するためのボタンを配置してほしいです。

実装しなくてよいもの

  • 別の画面から遷移する際に引数を受け取ること
  • 別の画面へ遷移する際に結果を渡すこと

交差点を検索する際に "Cross Street" を指定してより結果に含まれる可能性を上げる

概要

v3 の Venue 検索 API で交差点が出てこない件について Foursquare のサポートチケットを切って尋ねてみたところ location 属性の中にある "Cross Street" という属性を指定することで検索結果に出現させられるのではないかという提案を得た。これを(ローカル DB でのキャッシュを抜きにして)試してみて数多の交差点が表示されるようであるならば PR にしたい。

instrumented test を Firebase Test Lab にて走らせてみる

概要

related: #32

GitHub Actions が提供する x86_64 な仮想マシン上で x86_64 なヘッドレス Android を動作させ、そこで instrumented test を走らせると flaky な動作になってしまう(成功するはずのテストが不安定な実行環境のために失敗することがある)。

そこで、どうやら実機を用いてテストを走らせてくれるらしい Firebase Test Lab を CI から利用するようにしてみる。

方針

これらを参考にして実装してみる

Google Play で公開したい

概要

このアプリを Google Play で公開したい。

やること

  • プライバシーポリシーを用意する
  • アプリを審査してもらうための認証情報や操作方法を用意する
    • ユーザー自身に OAuth token の取得をさせたり埋め込ませたりするのをやめる
  • #39
  • チェックインを削除するための導線を作成する
    • 自分のデータの削除をリクエストする方法をユーザーに提供するため

「過去にチェックインした Venue 履歴」の実装

概要

現在周辺 Venue を取得するために利用している Foursquare の v3 API は、公式 Swarm アプリで得られる Venue を返してくれないことが多々ある。そのため、妥協案として、過去にチェックインした Venue の履歴を取得するための API を利用し、そこから再度チェックインできるようにしたい。

#12 と連携することで、「過去にチェックインした Venue をお気に入りに登録」することができるようにしたい。これによって、Foursquare の v3 API の弱さをカバーできるのではないかと考える。

やること

  • チェックイン履歴画面の実装(#34
  • 履歴を選択して、その Venue をお気に入りとして追加できるようにする

友達を指定して一緒にチェックインできるようにする

概要

Swarm アプリには、友達を指定して同時にチェックインするための機能がある。これと同等の機能を実装できると、友達を巻き込んで交差点にチェックインできるようになり、より便利である。特に運転手がチェックインできないときに助手席で交差点にチェックインしやすくなる。

実装するもの

以下の実装が必要である。

  • 友達一覧取得 API のクライアント
  • チェックイン作成 API で友達を指定できるクライアント
  • 友達選択画面
  • MainScreen での選択した友達の状態の保持

友達一覧取得 API のクライアント

具体的な API エンドポイントは後で調べる。
:library:foursquareclientpub.yusuke.foursquareclient.network 以下に FriendApiService を作成する。

チェックイン作成 API で友達を指定できるクライアント

以下の箇所に変更を加え、HTTP リクエスト内で友達を指定する。

@POST("/v2/checkins/add")
@Headers("Accept: application/json")
suspend fun createCheckin(
@Query("oauth_token")
oauthToken: String,
@Query("venueId")
venueId: String,
@Query("ll")
ll: String? = null,
@Query("shout")
shout: String? = null,
@Query("mentions")
mentions: String?,
@Query("broadcast")
broadcast: String?,
@Query("v")
v: String? = "20221002",
): CreateCheckinResponse

友達選択画面

友達一覧を取得するための API を CheckinApiService から呼び出せるようにする。
この画面に遷移するとき、引数として友達のリストを渡せるようにすること。また、この画面から返す結果は、同じ型の友達のリストとすること。
なお、画面間で共有する友達の型は navigation パッケージ以下に定義すること。

余裕があれば、instrumentation test で以下のことを検証する。

  • 引数で渡した友達が画面を開いた時点で選択されていること
  • 画面内で選択した友達が結果に包まれて帰ってくること

MainScreen での選択した友達の状態の保持

MainScreen では、友達選択画面で選択した友達の状態を保持し、またその状態と共に友達選択画面への遷移ができるようにする。
また、チェックインを作成する際には、その状態を見て一緒にチェックインする友達を指定してチェックインできるようにする。

なお、チェックイン作成前後で友達のリストは変化しない。

余裕があれば、instrumentation test で以下のことを検証する。

  • 選択した友達がチェックイン時に ViewModel のメソッド checkIn に渡されていること

Rwnovate による Compose Compiler と Kotlin のバージョンのアップデート PR をまとめるようにする

概要

Compose Compiler は各バージョンにおいて動作のためにある Kotlin のバージョンを要求するようになっており、Renovate で自動的に片方をアップデートしようとしても必ずテストが失敗し、人の手による手動アップデートが必要になってしまっている。

これを解決するため、依存パッケージをまとめて 1 つの PR でアップデートさせる Renovate の機能を使うようにする。

https://medium.com/androiddevelopers/automating-dependency-updates-in-a-compose-project-168ef5e89ac5 が参考になるはず(これを読んでいてやりたくなった)。

VibratorManager に直接依存しないようにし、`minSdk` を 27 まで落とす

概要

周囲には API レベル 27 までしかバージョンが上げられなかった端末がいくつかあり、それらで instrumented test を走らせることができたら面白いので minSdk を 27 まで落としたい。

このためには、少なくともまずは VibratorManager に直接依存しないようにするべきである。せっかく DI フレームワークを利用しているので、Interactor から端末を振動させるための関数を呼び出して利用する際、そのために Interactor の constructor で VibratorManager に近い interface を実装したものを注入することにし、その実装は API レベルが 31 以上とそうでない場合でそれぞれ違うものを利用するようにしたい。

入力した shout が適用されない

概要

shout(チェックインのコメント)を入力してチェックインしても、そのチェックインに shout が付いていない。

原因

coroutineScope.launch { viewModel.checkIn(venueId) }

onClick = { coroutineScope.launch { viewModel.checkIn(selectedVenueIdState) } },

この 2 行で、MainContract.ViewModel.checkIn に shout を渡せておらず、checkIn の方はデフォルト引数として null が使われてしまっているのが原因である。

Gradle version catalogs を導入して Renovate による自動アップデートを再度使えるようにする

概要

#68 を解消することができたが、その手法 #134 では Renovate による自動アップデートができなくなってしまっている。

https://docs.renovatebot.com/modules/manager/gradle/#file-matching より、Renovate は libs.versions.toml を見てくれるようである。そのため、Gradle version catalogs を導入し、https://github.com/private-yusuke/interscheckin/blob/fa7996438f8dd9846d2e76ce16953942e552d2cf/buildSrc/src/main/kotlin/LibraryVersions.kt を削除したい。

参考リンク

https://developer.android.com/build/migrate-to-catalogs

設定画面の各項目を別々の画面に分けて利用できるように整理する

概要

SettingsScreen に新規機能用の設定用の部品を追加すると煩雑になるため、各設定項目について画面を分けるようにし、それらにアクセスするための「設定一覧画面」を新しく作成したい。

「設定一覧画面」の形

以下のような形式で導線を作成する。

  • 「認証情報」
    • Foursquare 用の認証情報の設定を移植する
  • 「位置情報」
    • 位置情報へのアクセスを取得するための画面へ遷移するための行が表示される
  • 「リセット」
    • Venue のキャッシュをリセットするための行が表示される

Interscheckin のロゴが欲しい

概要

現状、Interscheckin にはロゴが無く、ホーム画面に追加してもアプリのアイコンは Android アプリのデフォルトのものとなっている。

他のアプリたちと見分けることが難しくなっており、見栄えも良いわけではないのでアイコンを追加したい。

位置情報取得時に前回のデータが 1, 2 回連続して渡されることがある

概要

"Update Venue list" ボタンを押下して位置情報の更新をかける際、移動前の場所の位置情報に似た値が 1, 2 回帰ってきて現在位置が素早く得られないことがある。

期待する動作は、ボタンの 1 回のみの押下ですぐに現在位置が帰ってくるようになることである。

対策として現状考えているもの

@SuppressLint("MissingPermission")
suspend fun FusedLocationProviderClient.currentLocation(): Location = suspendCoroutine { cont ->
    this.getCurrentLocation(CurrentLocationRequest.Builder().build(), null)
        .addOnSuccessListener { location ->
            cont.resume(location)
        }
}

以上のような関数を定義し、MainInteractor.fetchVenues 関数の中で呼び出して返り値をそのまま返す。
後でドライブしながら動作の検証を行い、これで期待した動作が得られたならば PR を作成して出すことにする。

Dependency Dashboard

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

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

  • Update kotlin (com.google.devtools.ksp, org.jetbrains.kotlin.plugin.serialization, org.jetbrains.kotlin.jvm, org.jetbrains.kotlin.android)

Detected dependencies

github-actions
.github/workflows/build_apk.yml
  • actions/checkout v4
  • actions/setup-java v4
  • actions/upload-artifact v4
  • ubuntu 22.04
.github/workflows/ci.yml
  • actions/checkout v4
  • actions/setup-java v4
  • actions/checkout v4
  • actions/setup-java v4
  • actions/checkout v4
  • actions/setup-java v4
  • actions/checkout v4
  • ubuntu 22.04
  • ubuntu 22.04
  • ubuntu 22.04
gradle
gradle.properties
settings.gradle.kts
build.gradle.kts
app/build.gradle.kts
  • composeOptions 1.5.10
gradle/libs.versions.toml
  • com.google.accompanist:accompanist-permissions 0.34.0
  • androidx.activity:activity-compose 1.8.2
  • androidx.compose:compose-bom 2024.02.02
  • androidx.core:core-ktx 1.12.0
  • androidx.core:core-splashscreen 1.0.1
  • androidx.fragment:fragment-ktx 1.6.2
  • androidx.test.ext:junit 1.1.5
  • androidx.lifecycle:lifecycle-runtime-ktx 2.7.0
  • androidx.lifecycle:lifecycle-viewmodel-ktx 2.7.0
  • io.coil-kt:coil-compose 2.6.0
  • androidx.datastore:datastore-preferences 1.0.0
  • io.gitlab.arturbosch.detekt:detekt-formatting 1.23.5
  • androidx.test.espresso:espresso-core 3.5.1
  • com.google.dagger:hilt-android-compiler 2.51
  • com.google.dagger:hilt-android 2.51
  • com.google.dagger:hilt-android-gradle-plugin 2.51
  • com.google.dagger:hilt-android-testing 2.51
  • com.google.dagger:hilt-compiler 2.51
  • androidx.hilt:hilt-navigation-compose 1.2.0
  • junit:junit 4.13.2
  • org.jetbrains.kotlinx:kotlinx-collections-immutable 0.3.7
  • org.jetbrains.kotlinx:kotlinx-serialization-protobuf 1.6.3
  • io.mockk:mockk 1.13.10
  • io.mockk:mockk-agent 1.13.10
  • io.mockk:mockk-android 1.13.10
  • androidx.navigation:navigation-compose 2.7.7
  • androidx.paging:paging-common 3.2.1
  • androidx.paging:paging-compose 3.2.1
  • com.google.android.gms:play-services-location 21.2.0
  • androidx.room:room-compiler 2.6.1
  • androidx.room:room-ktx 2.6.1
  • androidx.room:room-paging 2.6.1
  • androidx.room:room-runtime 2.6.1
  • com.github.anboralabs:spatia-room 0.2.9
  • com.google.crypto.tink:tink-android 1.12.0
  • com.twitter.compose.rules:detekt 0.0.26
  • androidx.appcompat:appcompat 1.6.1
  • com.squareup.retrofit2:retrofit 2.9.0
  • com.squareup.retrofit2:converter-moshi 2.9.0
  • com.squareup.moshi:moshi-kotlin 1.15.1
  • com.squareup.okhttp3:logging-interceptor 4.12.0
  • org.jetbrains.kotlinx:kotlinx-coroutines-core 1.8.0
  • org.jetbrains.kotlinx:kotlinx-coroutines-android 1.8.0
  • androidx.wear.compose:compose-material 1.3.0
  • com.android.application 8.3.0
  • com.android.library 8.3.0
  • org.jetbrains.kotlin.android 1.9.22
  • org.jetbrains.kotlin.jvm 1.9.22
  • org.jetbrains.kotlin.plugin.serialization 1.9.22
  • io.gitlab.arturbosch.detekt 1.23.5
  • com.google.devtools.ksp 1.9.22-1.0.18
  • com.autonomousapps.dependency-analysis 1.30.0
library/foursquare-client/build.gradle.kts
library/fusedlocationktx/build.gradle.kts
library/repositories/build.gradle.kts
watchapp/build.gradle.kts
  • composeOptions 1.5.10
gradle-wrapper
gradle/wrapper/gradle-wrapper.properties
  • gradle 8.6

  • Check this box to trigger a request for Renovate to run again on this repository

利便性のため、`FusedLocationProviderClient.getLastLocation` で得られる現在地を使うのをやめたい

概要

手元で開発しているときは FusedLocationProviderClient.requestLocationUpdates を呼んで定期的に位置情報を取得するようにしていたが、現在は FusedLocationProviderClient.getLastLocation で現在端末から得られる最新の位置情報を得るような実装に変更した。

その結果、すぐに現在の位置情報が欲しくなったときに得られず、基本的には数秒前の位置情報を元にチェックインしたり Venue の検索をしたりするようになってしまった。

解決方法

FusedLocationProviderClient.requestLocationUpdates を呼び出して最新の位置情報を端末に格納してもらうようリクエストするような実装方法に変えたい。
FusedLocationProviderClient.locationFlow をすでに実装していたので、MainInteractor.fetchLocation を、この Flow の first だけを取ってくる実装に変えたら解決できないだろうか。

BOM(Bill of Materials)で Jetpack Compose 関連のライブラリのバージョンを管理する

  • ef2c4ea$compose_ui_version からバージョンを取得するようにしたが、これは不適切なバージョン管理であると思う。
  • https://developer.android.com/jetpack/compose/setup#using-the-bom を参考にして BOM(Bill of Materials)を使ったほうがよさそう。
  • The Compose Bill of Materials (BOM) lets you manage all of your Compose library versions by specifying only the BOM’s version. The BOM itself has links to the stable versions of the different Compose libraries, in such a way that they work well together.

Originally posted by @private-yusuke in #23 (comment)

Kotlin 1.8.20 で入った data object(プレビュー)で sealed interface を継承する object を置き換える

概要

#117 で Kotlin 1.8.20 を使うようになったので、data object のプレビューが利用できるようになった1
data キーワードのおかげで toString() の出力が宣言した名前そのままというシンプルな形式になる利点と、構文上で data objectdata classを並べられると綺麗に見えそうという利点がある。

興味があるのでやってみる。

Footnotes

  1. https://kotlinlang.org/docs/whatsnew1820.html#preview-of-data-objects-for-symmetry-with-data-classes

初回起動時に位置情報の取得を許可してもらうための導入画面を作成する

概要

現在の実装では初回起動時に位置情報の取得を許可しないでいるといつまでたってもローディング中のような表示になってしまうのみであり非常に不親切な設計になっている。また、初回の位置情報取得許可を取った後であっても、それを取る前から位置情報の取得を実施しようとする動作をするのでどちらにせよ好ましくない動作をしている。

これを解決するために、初回起動時(または位置情報取得許可が取れていないとき)にはそこへの導線を置くための画面を作成して表示したい。

また、位置情報取得の許可がなければチェックイン履歴を見ることのみができるようにする。

MainScreen

位置情報を取得できない状態の場合は Snackbar でその旨を伝え、Snackbar にあるボタンから位置情報取得導線画面へ遷移するためのボタンを置く。

SettingsScreen

位置情報を取得できない状態の場合は位置情報取得導線画面へ遷移するためのボタンが押せるようにし、そうでない場合は許可済みであることを示しつつボタンを押せないようにする。

もしアプリ側で precise な位置情報の取得ができていないことを検知できるのであれば、かわりにそれを要求するための処理を実施させるようにする。

位置情報取得導線画面

アプリの初回起動時などの、位置情報を利用する旨をユーザーが一切決めていない状況のときは起動時にこの画面を表示するようにする。他の画面からこの画面に遷移することもできるが、それは曖昧な位置情報のみの取得許可または位置情報取得許可が出ていないときのみ許される。

  • このアプリで位置情報を利用するとチェックインができる旨を伝えるテキストと、位置情報取得許可ダイアログを呼び出すためのボタンが配置された画面
    • 詳細な位置情報を含めた許可が出たら MainScreen に遷移するためのボタンが配置された画面を表示する
    • 詳細な位置情報を含めた許可が出なかった場合は、チェックインをする際にそうなっていないと利便性が極めて落ちてしまうことを伝えつつ取得許可を求めるためのボタンを画面に表示する。この状態のままでも MainScreen に遷移できるような導線を置く。

モジュールを新たに作成して ViewModel を `:app` から分離する

概要

related: #223

Wear OS 向けのアプリケーションを作成するにあたって、Android 向けに今まで記述してきた ViewModel をそのまま流用したい。
MVVM アーキテクチャにおいては、ViewModel を流用して View(当アプリケーションでは Screen 関連の関数)をそれぞれの OS 向けに記述するという方針をとることに問題がないだろうと考えている。
そのため、まずは ViewModel を別モジュールに切り出し、それを Android アプリから参照するようにして、後に Wear OS 向けのアプリケーションからも参照するようにしたい。

実世界で短時間の移動をした際に前回から位置情報が変わっていないというメッセージが表示される場合がある

概要

related: #10, #48

#48 で、GPS を用いて現在地を取得する際に FusedLocationProviderClient.getCurrentLocation を呼び出すようにしたが、今度は #10 に近しい現象が再度発生するようになり、短時間で位置情報を更新したい際に困るようになってしまった。

すること

#11 で実装したものを再度使うように戻したい。

この Issue では取り扱わないが、今後は「n 秒ごとに位置情報を更新して格納し、ユーザーが Venue 一覧を更新したくなったらボタンを押すと格納されている位置周辺の Venue を取得するようにする機能」を実装したらより便利になるかもしれない。

「お気に入り Venue」機能の実装

概要

ユーザーが Venue をお気に入りに追加できる機能があるとうれしそう。

背景

交差点に限らず、よくチェックインする Venue では、毎回公式 Swarm アプリからその Venue を選んでチェックインをする手順が煩雑であると感じることがある。
これを解決するため、「お気に入り」に入れた Venue を表示する画面を作成し、そこから選ぶことでもチェックインできるようにしたい。

そのとき、不正なチェックイン(遠隔地からチェックインする行為)を防ぐため、現在位置から 1 km 以内でないとチェックインできないような制限も設けておきたい。

Venue の詳細画面を作成する

概要

メイン画面や履歴一覧画面で Venue に関する詳細な情報を表示するための画面を実装したい。

やること

  • DataStore
  • MVVM の部分
    • Contract の中に Interactor や ViewModel の interface を定義する
    • Module の中に DI をするための設定を書く
    • 上記 DataStore で得られたデータを画面で表示する情報のみを抽出した Model に translate するためのヘルパー関数を作成する
  • Screen の部分
    • Jetpack Compose で Venue に関する詳細な情報を表示できるようにする
    • 基本的に 4 dp を単位としてそれっぽいデザインを……
      • @Preview を適宜書いてみると良いかもしれない

HistoriesScreen が参考になりそう:#34
アーキテクチャの部分は VIPER から Presenter を消したようなものに近いです(どちらかというと MVVM なのかも)。https://techlife.cookpad.com/entry/2020/11/17/110000 が参考になるかもしれません

コミットをする前にしてほしいこと

PR の分け方

  • DataStore の作成をするところまで
  • MVVM と画面の部分は一緒にやっても良い
    • 最初は適当なデザイン(情報がテキストで表示されるのみ)で、次にしっかりとしたデザインにする、などの分け方をしてみてほしい

Wear OS 向けのアプリを書く

概要

@private-yusuke が趣味で Wear OS を搭載した Pixel Watch を取得し、せっかくなのでアプリを書きたいと考えている。
今は大学の前の交差点などで毎回スマホをポケットから取り出してチェックインしているが、これを腕時計で完結できたら非常に便利になると思われる。そこで、Wear OS 向けの Interscheckin 実装を作成したい。

方針

  • Interscheckin のビジネスロジック(今は ViewModel にいろいろ実装されているもの)を別モジュールに分割する
    • 現状の ViewModel をそのまま Wear OS 側から利用することができることを期待している(要検証)
  • Wear OS 向けのアプリを書く
    • とりあえず一番近い交差点の名前とその距離、そしてチェックインボタンだけ表示しておけばよい気がしている
    • チェックインが完了・失敗したらそれぞれのパターンに応じたバイブレーションをするようにしたい(スマホアプリとはタイミングが違うが、操作のフィードバックとして振動を感じられるような仕様にしたほうが便利そう)

`README.md` 用の画像を自動的に生成する

概要

related: #179
デザインの変更によって README.md に掲載している画像が現状のアプリの画面と異なっているとき、人間がわざわざスクリーンショットの撮影をして更新する必要があり、面倒である。
そこで、機械的にスクリーンショットを撮影できるようにしたい。

https://docs.fastlane.tools/getting-started/android/screenshots/ を参考にして fastlane の導入と自動テスト中の撮影ができるかもしれない。

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.