diff --git a/app/build.gradle b/app/build.gradle index 81570c0..1f44625 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -86,6 +86,10 @@ dependencies { // Dialog for adding a new location implementation 'com.afollestad.material-dialogs:core:3.1.0' implementation 'com.afollestad.material-dialogs:input:3.1.0' + + // drawer + implementation 'co.zsmb:materialdrawer-kt:2.0.1' + implementation "androidx.annotation:annotation:1.1.0" } diff --git a/app/src/main/java/bou/amine/apps/mteo/MainActivity.kt b/app/src/main/java/bou/amine/apps/mteo/MainActivity.kt index 9f46d82..6edc169 100644 --- a/app/src/main/java/bou/amine/apps/mteo/MainActivity.kt +++ b/app/src/main/java/bou/amine/apps/mteo/MainActivity.kt @@ -7,17 +7,29 @@ import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.location.LocationListener import android.location.LocationManager +import android.util.Log +import android.view.Menu +import android.view.MenuItem +import android.view.View import android.widget.Toast import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView import androidx.room.Room import bou.amine.apps.mteo.api.DarkSkyApi import bou.amine.apps.mteo.api.ForecastResponse import bou.amine.apps.mteo.persistence.MIGRATION_1_2 import bou.amine.apps.mteo.persistence.database.AppDatabase import bou.amine.apps.mteo.persistence.entities.LocationView +import co.zsmb.materialdrawerkt.builders.drawer +import co.zsmb.materialdrawerkt.draweritems.badgeable.primaryItem +import co.zsmb.materialdrawerkt.draweritems.badgeable.secondaryItem +import co.zsmb.materialdrawerkt.draweritems.divider import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.input.input +import com.mikepenz.materialdrawer.Drawer +import kotlinx.android.synthetic.main.activity_main.* import retrofit2.Call import retrofit2.Callback import retrofit2.Response @@ -30,11 +42,15 @@ class MainActivity : AppCompatActivity() { private lateinit var api: DarkSkyApi private lateinit var currentLocation: LocationView + private lateinit var locations: List + + private lateinit var drawer: Drawer override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + setSupportActionBar(bottom_app_bar) api = DarkSkyApi(this@MainActivity) @@ -43,29 +59,83 @@ class MainActivity : AppCompatActivity() { AppDatabase::class.java, "mteo-database" ).addMigrations(MIGRATION_1_2).build() + fab.setOnClickListener { checkPermission() } + + handleRefresh() + thread { - val locations = db.locationDao().locations() + locations = db.locationDao().locations() runOnUiThread { if (locations.isEmpty()) { checkPermission() } else { - currentLocation = locations[0] - fetchForecastData() + selectLocationAndFetch() + loadDrawer() + drawer.setSelection(locations[0].id.toLong(), false) } } } } + private fun handleRefresh() { + swipeRefreshLayout.setColorSchemeResources( + R.color.colorPrimary, + R.color.colorPrimaryDark, + R.color.colorAccent + ) + swipeRefreshLayout.setOnRefreshListener { + fetchForecastData() + } + } + + private fun loadDrawer() { + if (::drawer.isInitialized) { + drawer.closeDrawer() + } + drawer = drawer { + toolbar = toolBar + primaryItem("Locations") { + selectable = false + } + locations.map { + secondaryItem(it.name) { + identifier = it.id.toLong() + onClick { _, position, _ -> + selectLocationAndFetch(position - 1) + true + } + } + } + onItemLongClick {_, position, _ -> + val toRemove = locations[position - 1] + locations = locations.filterNot { it == toRemove } + loadDrawer() + thread { + db.locationDao().deleteLocation(toRemove) + } + true + } + } + } + + private fun selectLocationAndFetch(position: Int = 0) { + swipeRefreshLayout.isRefreshing = true + currentLocation = locations[position] + fetchForecastData() + } + private fun fetchForecastData() { thread { api.forecast(currentLocation.lat.toString(), currentLocation.lng.toString()).enqueue(object : Callback { override fun onFailure(call: Call, t: Throwable) { Toast.makeText(this@MainActivity, "Can't fetch forecast data !", Toast.LENGTH_LONG).show() + swipeRefreshLayout.isRefreshing = false } override fun onResponse(call: Call, response: Response) { Toast.makeText(this@MainActivity, "Ok", Toast.LENGTH_LONG).show() + swipeRefreshLayout.isRefreshing = false } }) @@ -114,10 +184,13 @@ class MainActivity : AppCompatActivity() { mLocationManager.removeUpdates(this) MaterialDialog(this@MainActivity).show { input { _, text -> - currentLocation = LocationView(location.latitude, location.longitude, text.toString()) - fetchForecastData() + locations += LocationView(location.latitude, location.longitude, text.toString()) + selectLocationAndFetch(locations.size - 1) thread { db.locationDao().insertLocation(currentLocation) + runOnUiThread { + loadDrawer() + } } } } @@ -147,4 +220,22 @@ class MainActivity : AppCompatActivity() { } } } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + val inflater = menuInflater + inflater.inflate(R.menu.bottom_app_bar, menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + when (item!!.itemId) { + R.id.alerts -> Toast.makeText(this@MainActivity, "alerts item is clicked!", Toast.LENGTH_SHORT).show() + R.id.currently -> Toast.makeText(this@MainActivity, "currently item is clicked!", Toast.LENGTH_SHORT).show() + R.id.daily -> Toast.makeText(this@MainActivity, "daily item is clicked!", Toast.LENGTH_SHORT).show() + R.id.hourly -> Toast.makeText(this@MainActivity, "hourly item is clicked!", Toast.LENGTH_SHORT).show() + R.id.minutely -> Toast.makeText(this@MainActivity, "minutely item is clicked!", Toast.LENGTH_SHORT).show() + } + + return true + } } diff --git a/app/src/main/java/bou/amine/apps/mteo/persistence/dao/LocationsDao.kt b/app/src/main/java/bou/amine/apps/mteo/persistence/dao/LocationsDao.kt index 2b28c57..a718af6 100644 --- a/app/src/main/java/bou/amine/apps/mteo/persistence/dao/LocationsDao.kt +++ b/app/src/main/java/bou/amine/apps/mteo/persistence/dao/LocationsDao.kt @@ -1,9 +1,6 @@ package bou.amine.apps.mteo.persistence.dao -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query +import androidx.room.* import bou.amine.apps.mteo.persistence.entities.LocationView @Dao @@ -13,4 +10,7 @@ interface LocationsDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertLocation(vararg location: LocationView) + + @Delete + fun deleteLocation(tag: LocationView) } \ No newline at end of file diff --git a/app/src/main/res/drawable-anydpi/ic_access_time.xml b/app/src/main/res/drawable-anydpi/ic_access_time.xml new file mode 100644 index 0000000..2239a4f --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_access_time.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_add_location.xml b/app/src/main/res/drawable-anydpi/ic_add_location.xml new file mode 100644 index 0000000..c046460 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_add_location.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_cloud_circle.xml b/app/src/main/res/drawable-anydpi/ic_cloud_circle.xml new file mode 100644 index 0000000..c0c7001 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_cloud_circle.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_error_outline.xml b/app/src/main/res/drawable-anydpi/ic_error_outline.xml new file mode 100644 index 0000000..a07a0f9 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_error_outline.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_hourglass_empty.xml b/app/src/main/res/drawable-anydpi/ic_hourglass_empty.xml new file mode 100644 index 0000000..d55d5c8 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_hourglass_empty.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_view_day.xml b/app/src/main/res/drawable-anydpi/ic_view_day.xml new file mode 100644 index 0000000..ee43f68 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_view_day.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 716af5a..de2cbee 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,19 +1,83 @@ - + tools:context=".MainActivity" + android:fitsSystemWindows="true"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_app_bar.xml b/app/src/main/res/menu/bottom_app_bar.xml new file mode 100644 index 0000000..0656594 --- /dev/null +++ b/app/src/main/res/menu/bottom_app_bar.xml @@ -0,0 +1,35 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 5885930..98cc548 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,11 +1,20 @@ - + + +