From 22ff78202a4de683c2513f0d627e9be6e9ab6234 Mon Sep 17 00:00:00 2001 From: Niko Diamadis Date: Mon, 30 May 2022 18:16:45 +0200 Subject: [PATCH] =?UTF-8?q?F=C3=BCge=20Jahresauswahl=20hinzu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/cyb3rko/techniklogger/MainActivity.kt | 55 +----- .../java/com/cyb3rko/techniklogger/Utils.kt | 43 +++++ .../fragments/ListingFragment.kt | 42 ++++- .../techniklogger/fragments/YearsFragment.kt | 117 +++++++++++++ .../techniklogger/recycler/YearAdapter.kt | 48 ++++++ app/src/main/res/layout/fragment_years.xml | 159 ++++++++++++++++++ .../main/res/layout/item_recycler_year.xml | 21 +++ app/src/main/res/menu/menu_main.xml | 5 + .../main/res/navigation/mobile_navigation.xml | 6 + 9 files changed, 438 insertions(+), 58 deletions(-) create mode 100644 app/src/main/java/com/cyb3rko/techniklogger/Utils.kt create mode 100644 app/src/main/java/com/cyb3rko/techniklogger/fragments/YearsFragment.kt create mode 100644 app/src/main/java/com/cyb3rko/techniklogger/recycler/YearAdapter.kt create mode 100644 app/src/main/res/layout/fragment_years.xml create mode 100644 app/src/main/res/layout/item_recycler_year.xml diff --git a/app/src/main/java/com/cyb3rko/techniklogger/MainActivity.kt b/app/src/main/java/com/cyb3rko/techniklogger/MainActivity.kt index 4bcc88f..e2acbfd 100644 --- a/app/src/main/java/com/cyb3rko/techniklogger/MainActivity.kt +++ b/app/src/main/java/com/cyb3rko/techniklogger/MainActivity.kt @@ -2,26 +2,19 @@ package com.cyb3rko.techniklogger import android.Manifest import android.annotation.SuppressLint -import android.content.Intent import android.content.SharedPreferences import android.os.Bundle import android.util.Log -import android.view.Menu -import android.view.MenuItem import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.navigation.NavController import androidx.navigation.findNavController import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.setupActionBarWithNavController -import com.afollestad.materialdialogs.MaterialDialog -import com.afollestad.materialdialogs.input.getInputField -import com.afollestad.materialdialogs.input.input import com.androidnetworking.AndroidNetworking import com.androidnetworking.error.ANError import com.androidnetworking.interfaces.StringRequestListener import com.cyb3rko.techniklogger.databinding.ActivityMainBinding -import java.util.* class MainActivity : AppCompatActivity() { private var _binding: ActivityMainBinding? = null @@ -43,7 +36,9 @@ class MainActivity : AppCompatActivity() { navController = findNavController(R.id.nav_host_fragment_activity_main) // Passing each menu ID as a set of Ids because each // menu should be considered as top level destinations. - val appBarConfiguration = AppBarConfiguration(setOf(R.id.navigation_listing)) + val appBarConfiguration = AppBarConfiguration( + setOf(R.id.navigation_years, R.id.navigation_listing) + ) setupActionBarWithNavController(navController, appBarConfiguration) sharedPref = getSharedPreferences("Safe", 0) @@ -51,7 +46,7 @@ class MainActivity : AppCompatActivity() { sharedPrefEditor.apply() if (sharedPref.getString("name", "") == "") { - showNameDialog() + showNameDialog(this, sharedPref, sharedPrefEditor) } else { updateCheck() } @@ -64,30 +59,6 @@ class MainActivity : AppCompatActivity() { ) } - private fun showNameDialog() { - val currentName = getSharedPreferences("Safe", 0).getString("name", "") - - MaterialDialog(this) - .cancelable(false) - .title(0, "Bitte gib deinen Namen ein") - .show { - input(hint = "Dein Name", prefill = currentName, waitForPositiveButton = false) { dialog, inputName -> - try { - if (!inputName[0].isUpperCase()) { - dialog.getInputField().error = "Der Anfangsbuchstabe sollte groß sein" - } - } catch (ignored: IndexOutOfBoundsException) { - } - - positiveButton(0, "Speichern") { - sharedPref.edit().putString("name", inputName.toString()).commit() - finish() - startActivity(Intent(applicationContext, MainActivity::class.java)) - } - } - } - } - private fun updateCheck() { AndroidNetworking.initialize(applicationContext) AndroidNetworking.get("https://git.aldiserver.de/api/v1/repos/niko/technik-logger-app/contents/app/build.gradle") @@ -108,22 +79,4 @@ class MainActivity : AppCompatActivity() { override fun onSupportNavigateUp(): Boolean { return navController.navigateUp() || super.onSupportNavigateUp() } - - override fun onCreateOptionsMenu(menu: Menu): Boolean { - // Inflate the menu; this adds items to the action bar if it is present. - menuInflater.inflate(R.menu.menu_main, menu) - return true - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - when (item.itemId) { - R.id.action_rename -> showNameDialog() - R.id.action_about -> navController.navigate(R.id.navigation_about) - } - - return super.onOptionsItemSelected(item) - } } diff --git a/app/src/main/java/com/cyb3rko/techniklogger/Utils.kt b/app/src/main/java/com/cyb3rko/techniklogger/Utils.kt new file mode 100644 index 0000000..77709be --- /dev/null +++ b/app/src/main/java/com/cyb3rko/techniklogger/Utils.kt @@ -0,0 +1,43 @@ +package com.cyb3rko.techniklogger + +import android.content.Intent +import android.content.SharedPreferences +import androidx.core.content.ContextCompat.startActivity +import com.afollestad.materialdialogs.MaterialDialog +import com.afollestad.materialdialogs.input.getInputField +import com.afollestad.materialdialogs.input.input + +internal const val CURRENT_YEAR = "current_year" +internal const val CURRENT_YEAR_NAME = "current_year_name" +internal const val COLUMN_JAHR = "jahr" +internal const val COLUMN_JAHR_NAME = "name" +internal const val COLUMN_TECHNIKER_NAME = "name" +internal const val SHARED_PREFERENCE = "Safe" + +internal fun showNameDialog( + activity: MainActivity, + sharedPref: SharedPreferences, + sharedPrefEditor: SharedPreferences.Editor +) { + val currentName = sharedPref.getString(COLUMN_TECHNIKER_NAME, "") + + MaterialDialog(activity) + .cancelable(false) + .title(0, "Bitte gib deinen Namen ein") + .show { + input(hint = "Dein Name", prefill = currentName, waitForPositiveButton = false) { dialog, inputName -> + try { + if (!inputName[0].isUpperCase()) { + dialog.getInputField().error = "Der Anfangsbuchstabe sollte groß sein" + } + } catch (ignored: IndexOutOfBoundsException) { + } + + positiveButton(0, "Speichern") { + sharedPrefEditor.putString("name", inputName.toString()).commit() + activity.finish() + startActivity(activity, Intent(activity, MainActivity::class.java), null) + } + } + } +} diff --git a/app/src/main/java/com/cyb3rko/techniklogger/fragments/ListingFragment.kt b/app/src/main/java/com/cyb3rko/techniklogger/fragments/ListingFragment.kt index fb2cd4d..c5fdc20 100644 --- a/app/src/main/java/com/cyb3rko/techniklogger/fragments/ListingFragment.kt +++ b/app/src/main/java/com/cyb3rko/techniklogger/fragments/ListingFragment.kt @@ -5,24 +5,25 @@ import android.content.Context import android.content.SharedPreferences import android.os.Bundle import android.util.Log -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup +import android.view.* import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager -import com.cyb3rko.techniklogger.R +import com.cyb3rko.techniklogger.* +import com.cyb3rko.techniklogger.COLUMN_JAHR +import com.cyb3rko.techniklogger.CURRENT_YEAR import com.cyb3rko.techniklogger.databinding.FragmentListingBinding import com.cyb3rko.techniklogger.recycler.ProjectEntryViewHolder import com.cyb3rko.techniklogger.recycler.ProjectViewState +import com.cyb3rko.techniklogger.showNameDialog import com.cyb3rko.techniklogger.table.ExportBuilder import com.parse.ParseObject import com.parse.ParseQuery import es.dmoral.toasty.Toasty -import me.ibrahimyilmaz.kiel.adapter.RecyclerViewAdapter -import me.ibrahimyilmaz.kiel.core.RecyclerViewHolder import java.text.SimpleDateFormat import java.util.* +import me.ibrahimyilmaz.kiel.adapter.RecyclerViewAdapter +import me.ibrahimyilmaz.kiel.core.RecyclerViewHolder class ListingFragment : Fragment() { private var _binding: FragmentListingBinding? = null @@ -38,13 +39,16 @@ class ListingFragment : Fragment() { private val binding get() = _binding!! override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + setHasOptionsMenu(true) _binding = FragmentListingBinding.inflate(inflater, container, false) val root = binding.root myContext = requireContext() sharedPref = myContext.getSharedPreferences("Safe", 0) sharedPrefEditor = sharedPref.edit() - sharedPrefEditor.apply() + if (sharedPref.getString(CURRENT_YEAR, "") == "") { + findNavController().navigate(R.id.navigation_years) + } binding.loadingAnimation.playAnimation() @@ -139,6 +143,13 @@ class ListingFragment : Fragment() { data.clear() val query = ParseQuery.getQuery("Einsatz") query.limit = 100000 + query.whereEqualTo( + COLUMN_JAHR, + ParseObject.createWithoutData( + "Jahr", + sharedPref.getString(CURRENT_YEAR, "") + ) + ) query.findInBackground { objects, e -> if (e == null) { @@ -243,4 +254,21 @@ class ListingFragment : Fragment() { override fun onAnimationRepeat(animation: Animator?) {} }) } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.menu_main, menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + when (item.itemId) { + R.id.action_year -> findNavController().navigate(R.id.navigation_years) + R.id.action_rename -> showNameDialog(requireActivity() as MainActivity, sharedPref, sharedPrefEditor) + R.id.action_about -> findNavController().navigate(R.id.navigation_about) + } + + return super.onOptionsItemSelected(item) + } } diff --git a/app/src/main/java/com/cyb3rko/techniklogger/fragments/YearsFragment.kt b/app/src/main/java/com/cyb3rko/techniklogger/fragments/YearsFragment.kt new file mode 100644 index 0000000..65bef0e --- /dev/null +++ b/app/src/main/java/com/cyb3rko/techniklogger/fragments/YearsFragment.kt @@ -0,0 +1,117 @@ +package com.cyb3rko.techniklogger.fragments + +import android.content.Context +import android.content.SharedPreferences +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.LinearLayoutManager +import com.cyb3rko.techniklogger.* +import com.cyb3rko.techniklogger.COLUMN_JAHR_NAME +import com.cyb3rko.techniklogger.CURRENT_YEAR +import com.cyb3rko.techniklogger.CURRENT_YEAR_NAME +import com.cyb3rko.techniklogger.SHARED_PREFERENCE +import com.cyb3rko.techniklogger.databinding.FragmentYearsBinding +import com.cyb3rko.techniklogger.recycler.YearAdapter +import com.parse.ParseObject +import com.parse.ParseQuery +import es.dmoral.toasty.Toasty + +class YearsFragment : Fragment() { + private var _binding: FragmentYearsBinding? = null + private lateinit var myContext: Context + private lateinit var yearAdapter: YearAdapter + private var data: MutableList = mutableListOf() + private lateinit var sharedPref: SharedPreferences + private lateinit var sharedPrefEditor: SharedPreferences.Editor + + // This property is only valid between onCreateView and onDestroyView. + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentYearsBinding.inflate(inflater, container, false) + val root = binding.root + myContext = requireContext() + return root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + sharedPref = myContext.getSharedPreferences(SHARED_PREFERENCE, Context.MODE_PRIVATE) + sharedPrefEditor = sharedPref.edit() + + binding.loadingAnimation.playAnimation() + + yearAdapter = YearAdapter { objectId, name -> + sharedPrefEditor.putString(CURRENT_YEAR, objectId) + sharedPrefEditor.putString(CURRENT_YEAR_NAME, name).commit() + findNavController().navigate(R.id.navigation_listing) + } + binding.recyclerView.apply { + layoutManager = LinearLayoutManager(myContext) + adapter = yearAdapter + } + + loadEntries() + + binding.swipeRefreshLayout.apply { + setProgressBackgroundColorSchemeResource(R.color.refreshLayoutBackground) + setColorSchemeResources(R.color.refreshLayoutArrow) + setOnRefreshListener { + loadEntries() + } + } + + binding.fab.setOnClickListener { + + } + } + + private fun loadEntries() { + val query = ParseQuery.getQuery("Jahr") + query.limit = -1 + query.cachePolicy = ParseQuery.CachePolicy.CACHE_THEN_NETWORK + query.orderByDescending(COLUMN_JAHR_NAME) + + query.findInBackground { objects, e -> + if (e == null) { + data = objects + showAnimation(false) + binding.swipeRefreshLayout.isRefreshing = false + yearAdapter.submitList(data) + } else { + binding.swipeRefreshLayout.isRefreshing = false + if (data.isEmpty()) { + showAnimation(true, false) + } + Toasty.error(myContext, "Abruf fehlgeschlagen", Toasty.LENGTH_SHORT).show() + Log.e("TechnikLogger.JahrSuche", e.message.toString()) + } + } + + + } + + private fun showAnimation(show: Boolean, connected: Boolean = true) { + val viewVisibility = if (show) View.VISIBLE else View.INVISIBLE + val newSpeed = if (!connected) 1.2f else 1.5f + val animation = if (connected) "loading.json" else "no-connection.json" + binding.apply { + loadingAnimation.apply { + setAnimation(animation) + speed = newSpeed + visibility = viewVisibility + playAnimation() + } + } + } +} diff --git a/app/src/main/java/com/cyb3rko/techniklogger/recycler/YearAdapter.kt b/app/src/main/java/com/cyb3rko/techniklogger/recycler/YearAdapter.kt new file mode 100644 index 0000000..4207be9 --- /dev/null +++ b/app/src/main/java/com/cyb3rko/techniklogger/recycler/YearAdapter.kt @@ -0,0 +1,48 @@ +package com.cyb3rko.techniklogger.recycler + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.cardview.widget.CardView +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.cyb3rko.techniklogger.R +import com.parse.ParseObject + +class YearAdapter( + val action: (objectId: String, year: String) -> Unit +) : ListAdapter(YearDiffCallback) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.item_recycler_year, parent, false) + + return ViewHolder(view) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val entry = getItem(position) + val name = entry.getString("name")!! + holder.nameView.text = name + holder.cardView.setOnClickListener { + action(entry.objectId, name) + } + } + + class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { + val cardView: CardView = view.findViewById(R.id.root) + val nameView: TextView = view.findViewById(R.id.name_text) + } + + object YearDiffCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: ParseObject, newItem: ParseObject): Boolean { + return oldItem.objectId == newItem.objectId + } + + override fun areContentsTheSame(oldItem: ParseObject, newItem: ParseObject): Boolean { + return oldItem.getString("name") == newItem.getString("name") + } + } +} diff --git a/app/src/main/res/layout/fragment_years.xml b/app/src/main/res/layout/fragment_years.xml new file mode 100644 index 0000000..b82e1cf --- /dev/null +++ b/app/src/main/res/layout/fragment_years.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_recycler_year.xml b/app/src/main/res/layout/item_recycler_year.xml new file mode 100644 index 0000000..22cba55 --- /dev/null +++ b/app/src/main/res/layout/item_recycler_year.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index cc9d304..d6f771f 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -2,6 +2,11 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="com.cyb3rko.techniklogger.MainActivity"> + + + +