diff --git a/app/build.gradle b/app/build.gradle index c14be9e..15c0c73 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,6 +39,7 @@ dependencies { implementation 'com.jaredrummler:android-device-names:1.1.8' implementation 'com.github.mukeshsolanki:easypreferences:1.0.6' + implementation 'com.romandanylyk:pageindicatorview:1.0.3@aar' def lifecycle_version = "2.0.0" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" diff --git a/app/src/main/java/com/denizd/substitutionplan/DataFetcher.kt b/app/src/main/java/com/denizd/substitutionplan/DataFetcher.kt index aeb4bef..0bfd35c 100644 --- a/app/src/main/java/com/denizd/substitutionplan/DataFetcher.kt +++ b/app/src/main/java/com/denizd/substitutionplan/DataFetcher.kt @@ -24,7 +24,6 @@ import org.jsoup.Jsoup import org.jsoup.nodes.Document import org.jsoup.select.Elements import java.lang.IndexOutOfBoundsException -import java.lang.NullPointerException import java.net.URL import java.net.URLConnection import java.text.SimpleDateFormat diff --git a/app/src/main/java/com/denizd/substitutionplan/FoodFragment.kt b/app/src/main/java/com/denizd/substitutionplan/FoodFragment.kt index bd49f72..7ec0260 100644 --- a/app/src/main/java/com/denizd/substitutionplan/FoodFragment.kt +++ b/app/src/main/java/com/denizd/substitutionplan/FoodFragment.kt @@ -93,7 +93,7 @@ class FoodFragment : Fragment(R.layout.food_layout) { val mRootView = rootView private val fadeOut = AnimationUtils.loadAnimation(context, R.anim.fade_out) private val handler = Handler(Looper.getMainLooper()) - private var exceptionOccured = false + private var exceptionOccurred = false override fun doInBackground(vararg params: Void?): Void? { try { @@ -156,14 +156,14 @@ class FoodFragment : Fragment(R.layout.food_layout) { progressBar.progress = 100 mEasyPrefs.putListString("foodListPrefs", foodList) - } catch (e: Exception) { exceptionOccured = true } + } catch (e: Exception) { exceptionOccurred = true } return null } override fun onPostExecute(result: Void?) { super.onPostExecute(result) - if (!exceptionOccured) { + if (!exceptionOccurred) { try { mRecyclerView.removeAllViews() mFoodArrayList.removeAll(mFoodArrayList) @@ -196,6 +196,4 @@ class FoodFragment : Fragment(R.layout.food_layout) { } } } - - } \ No newline at end of file diff --git a/app/src/main/java/com/denizd/substitutionplan/Main.kt b/app/src/main/java/com/denizd/substitutionplan/Main.kt index f9ff783..fbe85d7 100644 --- a/app/src/main/java/com/denizd/substitutionplan/Main.kt +++ b/app/src/main/java/com/denizd/substitutionplan/Main.kt @@ -31,6 +31,7 @@ import androidx.core.content.ContextCompat import androidx.core.widget.NestedScrollView import androidx.fragment.app.Fragment import androidx.recyclerview.widget.RecyclerView +import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.appbar.AppBarLayout import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomsheet.BottomSheetBehavior @@ -128,9 +129,7 @@ class Main : AppCompatActivity(R.layout.activity_main) { bottomSheetCloser.visibility = View.GONE } } - - override fun onSlide(bottomSheet: View, slideOffset: Float) { - } + override fun onSlide(bottomSheet: View, slideOffset: Float) {} }) bottomSheetCloser.setOnClickListener { @@ -276,12 +275,14 @@ class Main : AppCompatActivity(R.layout.activity_main) { toolbarTxt.text = getString(R.string.foodmenu) } R.id.openinfopanel -> { - if (bottomSheetBehaviour.state == BottomSheetBehavior.STATE_COLLAPSED) { - bottomSheetBehaviour.state = BottomSheetBehavior.STATE_EXPANDED - } else if (bottomSheetBehaviour.state == BottomSheetBehavior.STATE_EXPANDED) { - bottomSheetBehaviour.state = BottomSheetBehavior.STATE_COLLAPSED - } - fragmentLoading = false +// if (bottomSheetBehaviour.state == BottomSheetBehavior.STATE_COLLAPSED) { +// bottomSheetBehaviour.state = BottomSheetBehavior.STATE_EXPANDED +// } else if (bottomSheetBehaviour.state == BottomSheetBehavior.STATE_EXPANDED) { +// bottomSheetBehaviour.state = BottomSheetBehavior.STATE_COLLAPSED +// } +// fragmentLoading = false + fragment = NewsFragment() + toolbarTxt.text = getString(R.string.news) } R.id.settings -> { fragment = SettingsFragment() @@ -317,6 +318,15 @@ class Main : AppCompatActivity(R.layout.activity_main) { } } catch (e: NullPointerException) {} } + R.id.openinfopanel -> { + try { + val nsvnewscard = findViewById(R.id.nsvnewscard) + nsvnewscard.post { + nsvnewscard.smoothScrollTo(0, 0) + bottomSheetBehaviour.state = BottomSheetBehavior.STATE_COLLAPSED + } + } catch (e: NullPointerException) {} + } R.id.settings -> { try { val nsv = findViewById(R.id.nsvsettings) diff --git a/app/src/main/java/com/denizd/substitutionplan/News.kt b/app/src/main/java/com/denizd/substitutionplan/News.kt new file mode 100644 index 0000000..5b6e06b --- /dev/null +++ b/app/src/main/java/com/denizd/substitutionplan/News.kt @@ -0,0 +1,3 @@ +package com.denizd.substitutionplan + +class News(val title: String, val content: String) diff --git a/app/src/main/java/com/denizd/substitutionplan/NewsAdapter.kt b/app/src/main/java/com/denizd/substitutionplan/NewsAdapter.kt new file mode 100644 index 0000000..0df7225 --- /dev/null +++ b/app/src/main/java/com/denizd/substitutionplan/NewsAdapter.kt @@ -0,0 +1,47 @@ +package com.denizd.substitutionplan + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView + +import java.util.ArrayList +import androidx.recyclerview.widget.RecyclerView + +class NewsAdapter(news: ArrayList) : RecyclerView.Adapter() { + private var mNews: List? = null + + class CardViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + var title = itemView.findViewById(R.id.title) + var content = itemView.findViewById(R.id.content) + } + + init { + mNews = news + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder { + val v = LayoutInflater.from(parent.context).inflate(R.layout.news_card, parent, false) + return CardViewHolder(v) + } + + fun getNewsAt(i: Int): News { + return mNews!![i] + } + + override fun onBindViewHolder(holder: CardViewHolder, position: Int) { + val currentItem = mNews!![position] + + holder.title.text = currentItem.title + holder.content.text = currentItem.content + } + + override fun getItemCount(): Int { + return mNews!!.size + } + + fun setNews(news: List) { + mNews = news + notifyDataSetChanged() + } +} diff --git a/app/src/main/java/com/denizd/substitutionplan/NewsFragment.kt b/app/src/main/java/com/denizd/substitutionplan/NewsFragment.kt new file mode 100644 index 0000000..87408c5 --- /dev/null +++ b/app/src/main/java/com/denizd/substitutionplan/NewsFragment.kt @@ -0,0 +1,144 @@ +package com.denizd.substitutionplan + +import android.content.Context +import android.content.SharedPreferences +import android.os.AsyncTask +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.preference.PreferenceManager +import android.view.View +import android.view.animation.Animation +import android.view.animation.AnimationUtils +import android.widget.FrameLayout +import android.widget.ProgressBar +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import androidx.viewpager.widget.ViewPager +import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.snackbar.Snackbar +import com.madapps.prefrences.EasyPrefrences +import com.rd.PageIndicatorView +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import org.jsoup.select.Elements +import java.lang.IndexOutOfBoundsException + + + +class NewsFragment : Fragment(R.layout.news) { + + private lateinit var mContext: Context + private lateinit var prefs: SharedPreferences + private lateinit var edit: SharedPreferences.Editor + private lateinit var easyPrefs: EasyPrefrences + private lateinit var pageIndicatorView: PageIndicatorView + + override fun onAttach(context: Context) { + super.onAttach(context) + mContext = context + prefs = PreferenceManager.getDefaultSharedPreferences(mContext) + edit = prefs.edit() + easyPrefs = EasyPrefrences(mContext) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { // TODO go on stackoverflow and get the necessary code lol + super.onViewCreated(view, savedInstanceState) + val pullToRefresh = view.findViewById(R.id.pullToRefresh) + + val viewPager2 = view.findViewById(R.id.viewPager2) + val list = ArrayList() + val adapter = NewsAdapter(list) + viewPager2.orientation = ViewPager2.ORIENTATION_HORIZONTAL + viewPager2.adapter = adapter + + pageIndicatorView = view.findViewById(R.id.indicator) + + viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + pageIndicatorView.selection = position + } + }) + + pageIndicatorView.count = 0 + pageIndicatorView.selection = 0 + + pullToRefresh.isRefreshing = true + FetchNews(mContext, adapter, list, pageIndicatorView, viewPager2, pullToRefresh, view.rootView).execute() + + pullToRefresh.setOnRefreshListener { + pullToRefresh.isRefreshing = true + FetchNews(mContext, adapter, list, pageIndicatorView, viewPager2, pullToRefresh, view.rootView).execute() + } + } + + class FetchNews(context: Context, adapter: NewsAdapter, arrayList: ArrayList, pageIndicatorView: PageIndicatorView, viewPager2: ViewPager2, + swipeRefreshLayout: SwipeRefreshLayout, rootView: View) : AsyncTask() { + + private val mContext = context + private val mAdapter = adapter + private val mArrayList = arrayList + private val mPageIndicatorView = pageIndicatorView + private val mViewPager2 = viewPager2 + private val frameLayout = rootView.findViewById(R.id.frameLayoutNews) + private var foodList = ArrayList() + private lateinit var foodElements: Elements + private lateinit var doc: Document + private val pullToRefresh = swipeRefreshLayout + private lateinit var progressBar: ProgressBar + val mRootView = rootView + private val fadeOut = AnimationUtils.loadAnimation(context, R.anim.fade_out) + private val handler = Handler(Looper.getMainLooper()) + private var exceptionOccured = false + private var size = 0 + + override fun doInBackground(vararg params: Void?): Void? { + try { + doc = Jsoup.connect("http://307.joomla.schule.bremen.de/index.php/schulleben/aktuelles").maxBodySize(0).get() + val blog = doc.getElementsByClass("blog").first() + val a = blog.getElementsByTag("h2") + + size = a.size + + for (i in 0 until a.size) { +// var searching = true + var content = "" + for (e in a[i].parent().parent().getElementsByTag("p")) { + if (e.text().isNotEmpty()) { + if (content.isEmpty()) { + content = e.text() + } else { + content += "\n\n" + e.text() + } + } + } + mArrayList.add(News(a[i].text(), content)) + } + + } catch (e: Exception) { exceptionOccured = true } + return null + } + + override fun onPostExecute(result: Void?) { + super.onPostExecute(result) + + if (!exceptionOccured) { + mAdapter.setNews(mArrayList) + frameLayout.scheduleLayoutAnimation() + mPageIndicatorView.count = size + mPageIndicatorView.selection = 0 + mViewPager2.setCurrentItem(0, true) + pullToRefresh.isRefreshing = false + + } else { + pullToRefresh.isRefreshing = false + val snackbarview = mRootView.findViewById(R.id.coordination) + Snackbar.make(snackbarview, mContext.getText(R.string.nointernet), Snackbar.LENGTH_LONG) + .setAction("Action", null).show() + + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt b/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt index 6678f7c..f22e723 100644 --- a/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt +++ b/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt @@ -199,6 +199,7 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen createDialog("Licences", "Libraries:\n • Android Device Names © 2015 Jared Rummler, licensed under the Apache Licence, Version 2.0" + "\n • EasyPreferences © 2018 Mukesh Solanki, licensed under the MIT Licence" + "\n • jsoup HTML parser © 2009-2018 Jonathan Hedley, licensed under the open source MIT Licence" + + "\n • PageIndicatorView © 2017 Roman Danylyk, licensed under the Apache Licence, Version 2.0" + "\n\nFont:\n • Manrope © 2018-2019 Michael Sharanda, licensed under the SIL Open Font Licence 1.1" + "\n\nIcons:\n • bqlqn\n • fjstudio\n • Freepik\n • Smashicons\n • © 2013-2019 Freepik Company S.L., licensed under Creative Commons BY 3.0" + "\n\nMarketing & Publishing:\n • Leon Becker\n • Alex Lick\n • Batuhan Özcan\n • Erich Kerkesner") @@ -387,7 +388,7 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen } "2018-04-20" -> { try { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.youtube.com/watch?v=u8tdT5pAE34")) + val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.youtube.com/watch?v=Jc2xfYuLWgE")) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).setPackage("com.google.android.youtube") startActivity(intent) } catch (e: ActivityNotFoundException) { diff --git a/app/src/main/res/layout/just_a_card.xml b/app/src/main/res/layout/just_a_card.xml index a3fe83e..f86b8df 100644 --- a/app/src/main/res/layout/just_a_card.xml +++ b/app/src/main/res/layout/just_a_card.xml @@ -5,7 +5,7 @@ android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" android:backgroundTint="@color/lightbackground" - app:cardCornerRadius="4dp" + app:cardCornerRadius="8dp" android:clickable="true" android:focusable="true" android:layout_marginStart="8dp" diff --git a/app/src/main/res/layout/news.xml b/app/src/main/res/layout/news.xml new file mode 100644 index 0000000..05f9cec --- /dev/null +++ b/app/src/main/res/layout/news.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/news_card.xml b/app/src/main/res/layout/news_card.xml new file mode 100644 index 0000000..b75c0e8 --- /dev/null +++ b/app/src/main/res/layout/news_card.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/nav_items.xml b/app/src/main/res/menu/nav_items.xml index 507125e..b78e4e8 100644 --- a/app/src/main/res/menu/nav_items.xml +++ b/app/src/main/res/menu/nav_items.xml @@ -19,7 +19,7 @@ Zeige Info-Tab in Navigationsleisete "Zuletzt aktualisiert: " Aktiviert den Nachtmodus + News (Alpha) \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8ed16a0..1279f38 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -140,4 +140,6 @@ Enables night mode + News (Alpha) +