From f937f1553db471227e91f44e0b70cf0bf638fa1c Mon Sep 17 00:00:00 2001 From: Nareshkumar Rao Date: Wed, 24 Mar 2021 00:39:10 +0100 Subject: [PATCH] implemented most functionality. notifications cannot be turned off --- .idea/dictionaries/naresh.xml | 9 ++ app/build.gradle | 23 ++-- app/src/main/AndroidManifest.xml | 13 +- app/src/main/ic_launcher-playstore.png | Bin 0 -> 44624 bytes .../nareshkumarrao/eiweblog/AboutActivity.kt | 36 ++++++ .../nareshkumarrao/eiweblog/MainActivity.kt | 64 ++++------ .../eiweblog/NotificationSettingsActivity.kt | 17 +++ .../nareshkumarrao/eiweblog/UpdateWorker.kt | 36 ++++++ .../com/nareshkumarrao/eiweblog/Utilities.kt | 115 +++++++++++++++-- .../eiweblog/ui/main/ItemArticleAdapter.kt | 16 ++- .../eiweblog/ui/main/SectionsFragment.kt | 44 ++++++- .../eiweblog/ui/main/SectionsPagerAdapter.kt | 2 +- .../main/res/drawable-hdpi/ic_stat_name.png | Bin 0 -> 645 bytes .../main/res/drawable-mdpi/ic_stat_name.png | Bin 0 -> 360 bytes .../main/res/drawable-xhdpi/ic_stat_name.png | Bin 0 -> 817 bytes .../main/res/drawable-xxhdpi/ic_stat_name.png | Bin 0 -> 1434 bytes .../res/drawable-xxxhdpi/ic_stat_name.png | Bin 0 -> 2108 bytes .../main/res/drawable/toolbar_dropshadow.xml | 7 ++ app/src/main/res/layout/activity_about.xml | 116 ++++++++++++++++++ app/src/main/res/layout/activity_main.xml | 2 +- .../layout/activity_notification_settings.xml | 63 ++++++++++ app/src/main/res/layout/fragment_sections.xml | 16 ++- app/src/main/res/menu/toolbar_menu.xml | 10 +- .../res/mipmap-anydpi-v26/ic_launcher.xml | 4 +- .../mipmap-anydpi-v26/ic_launcher_round.xml | 4 +- app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 3593 -> 2760 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 0 -> 3611 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 5339 -> 4690 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2636 -> 2155 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 0 -> 2086 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 3388 -> 3209 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 4926 -> 4612 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 0 -> 5365 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 7472 -> 7527 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 7909 -> 6519 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 0 -> 9246 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 11873 -> 11140 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 10652 -> 9890 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 0 -> 13690 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 16570 -> 17157 bytes app/src/main/res/values-night/themes.xml | 16 --- .../res/values/ic_launcher_background.xml | 4 + app/src/main/res/values/strings.xml | 24 +++- app/src/main/res/values/themes.xml | 5 +- images/launcher.png | Bin 0 -> 28060 bytes images/launcher.svg | 82 +++++++++++++ 46 files changed, 628 insertions(+), 100 deletions(-) create mode 100644 .idea/dictionaries/naresh.xml create mode 100644 app/src/main/ic_launcher-playstore.png create mode 100644 app/src/main/java/com/nareshkumarrao/eiweblog/AboutActivity.kt create mode 100644 app/src/main/java/com/nareshkumarrao/eiweblog/NotificationSettingsActivity.kt create mode 100644 app/src/main/java/com/nareshkumarrao/eiweblog/UpdateWorker.kt create mode 100644 app/src/main/res/drawable-hdpi/ic_stat_name.png create mode 100644 app/src/main/res/drawable-mdpi/ic_stat_name.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_stat_name.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_stat_name.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_stat_name.png create mode 100644 app/src/main/res/drawable/toolbar_dropshadow.xml create mode 100644 app/src/main/res/layout/activity_about.xml create mode 100644 app/src/main/res/layout/activity_notification_settings.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png delete mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values/ic_launcher_background.xml create mode 100644 images/launcher.png create mode 100644 images/launcher.svg diff --git a/.idea/dictionaries/naresh.xml b/.idea/dictionaries/naresh.xml new file mode 100644 index 0000000..4547fe3 --- /dev/null +++ b/.idea/dictionaries/naresh.xml @@ -0,0 +1,9 @@ + + + + elektro + hsdsans + weblog + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 6374795..20e8765 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,16 +35,19 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.2.0' - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'com.google.android.material:material:1.1.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0' - implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' - testImplementation 'junit:junit:4.+' - androidTestImplementation 'androidx.test.ext:junit:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.3.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0' + implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' implementation 'com.android.volley:volley:1.2.0' - implementation "com.squareup.okhttp3:okhttp:4.9.0" + implementation "androidx.work:work-runtime-ktx:2.5.0" + + } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 48d335b..21250d8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,8 @@ - + + + + - - \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..08a37e86370f51f2cd7989b177879fc405ae76df GIT binary patch literal 44624 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.id.about_toolbar) + setSupportActionBar(aboutToolbar) + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowTitleEnabled(false) + } + + fun sendBeer(view: View) { + startActivity( Intent( + Intent.ACTION_VIEW, + Uri.parse("https://paypal.me/naresh97") + )) + } + + fun githubRepo(view: View){ + startActivity( Intent( + Intent.ACTION_VIEW, + Uri.parse("https://github.com/naresh97/ei-weblog-android") + )) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/MainActivity.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/MainActivity.kt index 99f6fb0..cfeb7ec 100644 --- a/app/src/main/java/com/nareshkumarrao/eiweblog/MainActivity.kt +++ b/app/src/main/java/com/nareshkumarrao/eiweblog/MainActivity.kt @@ -1,17 +1,23 @@ package com.nareshkumarrao.eiweblog +import android.app.NotificationChannel +import android.app.NotificationManager +import android.content.Context +import android.content.Intent +import android.os.Build import android.os.Bundle -import android.util.Log import android.view.Menu +import android.view.MenuItem import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.viewpager.widget.ViewPager -import com.android.volley.VolleyLog +import androidx.work.PeriodicWorkRequestBuilder +import androidx.work.WorkManager +import androidx.work.WorkRequest import com.google.android.material.tabs.TabLayout -import com.nareshkumarrao.eiweblog.ui.main.Article import com.nareshkumarrao.eiweblog.ui.main.SectionsPagerAdapter -import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit class MainActivity : AppCompatActivity() { @@ -26,50 +32,32 @@ class MainActivity : AppCompatActivity() { val tabs: TabLayout = findViewById(R.id.tabs) tabs.setupWithViewPager(viewPager) - val myToolbar = findViewById(R.id.toolbar) as Toolbar + val myToolbar = findViewById(R.id.about_toolbar) as Toolbar setSupportActionBar(myToolbar) - VolleyLog.DEBUG = true + Utilities.createNotificationChannel(this) - /*val queue = Volley.newRequestQueue(this) - val url = "https://www.reddit.com" - val stringRequest = StringRequest( - Request.Method.GET, url, - { response -> - Log.d("XMLLIST", "got response!") - Log.d("XMLLIST", "$response") - }, - { error -> Log.e("XMLLIST", error.toString()) }) - stringRequest.retryPolicy = DefaultRetryPolicy( - DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, - DefaultRetryPolicy.DEFAULT_MAX_RETRIES, - DefaultRetryPolicy.DEFAULT_BACKOFF_MULT - ) - queue.add(stringRequest)*/ + val uploadWorkRequest: WorkRequest = + PeriodicWorkRequestBuilder(1, TimeUnit.HOURS) + .build() + WorkManager.getInstance(this).enqueue(uploadWorkRequest) - val thread = Thread { - try { - Log.d("XMLLIST", "Starting network request thread.") - val client = OkHttpClient() - val request = okhttp3.Request.Builder().url("https://google.com/").build() - val response = client.newCall(request).execute() - Log.d("XMLLIST", response.toString()) - } catch (e: Exception) { - e.printStackTrace() - } - } - thread.start() } - fun logArticles(articles: List
){ - Log.i("XMLLIST", articles.toString()) - } - override fun onCreateOptionsMenu(menu: Menu?): Boolean { - //Utilities.weblogXML(baseContext, ::logArticles) menuInflater.inflate(R.menu.toolbar_menu, menu); return true; } + + fun showNotificationSettings(item: MenuItem){ + val intent = Intent(this, NotificationSettingsActivity::class.java) + startActivity(intent) + } + + fun showAbout(item: MenuItem){ + val intent = Intent(this, AboutActivity::class.java) + startActivity(intent) + } } \ No newline at end of file diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/NotificationSettingsActivity.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/NotificationSettingsActivity.kt new file mode 100644 index 0000000..4dd2d7a --- /dev/null +++ b/app/src/main/java/com/nareshkumarrao/eiweblog/NotificationSettingsActivity.kt @@ -0,0 +1,17 @@ +package com.nareshkumarrao.eiweblog + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import androidx.appcompat.widget.Toolbar + +class NotificationSettingsActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_notification_settings) + + val notificationsToolbar = this.findViewById(R.id.notification_toolbar) + setSupportActionBar(notificationsToolbar) + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowTitleEnabled(false) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/UpdateWorker.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/UpdateWorker.kt new file mode 100644 index 0000000..bbc3760 --- /dev/null +++ b/app/src/main/java/com/nareshkumarrao/eiweblog/UpdateWorker.kt @@ -0,0 +1,36 @@ +package com.nareshkumarrao.eiweblog + +import android.content.Context +import androidx.work.Worker +import androidx.work.WorkerParameters +import java.math.BigInteger +import java.security.MessageDigest + +class UpdateWorker(private val context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { + override fun doWork(): Result { + + Utilities.weblogList(context) { articles -> + val lastArticle = Utilities.getLatestRelevantArticle(articles)!! + val hashString = lastArticle.title + lastArticle.content + lastArticle.date + val oldHash = md5(hashString) + + Utilities.fetchWeblogXML(applicationContext){newArticles -> + val lastNewArticle = Utilities.getLatestRelevantArticle(newArticles)!! + val newHashString = lastNewArticle.title + lastNewArticle.content + lastNewArticle.date + val newHash = md5(newHashString) + + if(oldHash != newHash){ + Utilities.sendNotification(context, lastNewArticle, newArticles.size) + } + } + } + + return Result.success() + } + + private fun md5(input:String): String { + val md = MessageDigest.getInstance("MD5") + return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0') + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/Utilities.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/Utilities.kt index 199cc08..07489f3 100644 --- a/app/src/main/java/com/nareshkumarrao/eiweblog/Utilities.kt +++ b/app/src/main/java/com/nareshkumarrao/eiweblog/Utilities.kt @@ -1,35 +1,74 @@ package com.nareshkumarrao.eiweblog -import android.content.ContentValues +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Intent import android.content.Context +import android.os.Build import android.util.Log import android.util.Xml +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import androidx.core.text.HtmlCompat import com.android.volley.Request -import com.android.volley.Response import com.android.volley.toolbox.StringRequest import com.android.volley.toolbox.Volley import com.nareshkumarrao.eiweblog.ui.main.Article import org.xmlpull.v1.XmlPullParser import java.io.StringReader + internal object Utilities { - fun weblogXML(context: Context, function: (d: List
) -> Unit) { + + fun weblogList(context: Context?, function: (d: List
) -> Unit){ + val sharedPref = context?.getSharedPreferences(context?.getString(R.string.preference_file_key), Context.MODE_PRIVATE) + val weblogResponse = sharedPref?.getString( context?.getString(R.string.weblog_response_key), null) + if (weblogResponse == null){ + fetchWeblogXML(context, function) + return + } + + val parser: XmlPullParser = Xml.newPullParser() + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false) + parser.setInput( StringReader(weblogResponse) ) + parser.nextTag() + function(parseXML(parser)) + } + + fun fetchWeblogXML(context: Context?, function: (d: List
) -> Unit) { val queue = Volley.newRequestQueue(context) - val url = "https://www.google.com" + val url = context?.getString(R.string.weblog_xml_url) val stringRequest = StringRequest(Request.Method.GET, url, { response -> - Log.d("XMLLIST", "got response!") - // Display the first 500 characters of the response string. - Log.d("XMLLIST", "$response") + val responseStr = String(response.toByteArray(Charsets.ISO_8859_1), Charsets.UTF_8) + + val sharedPref = context?.getSharedPreferences(context?.getString(R.string.preference_file_key), Context.MODE_PRIVATE) + if (sharedPref != null) { + with (sharedPref.edit()) { + putString(context?.getString(R.string.weblog_response_key), responseStr) + apply() + } + } + + + + val parser: XmlPullParser = Xml.newPullParser() + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false) + //Log.d("XMLLIST", responseStr ) + parser.setInput( StringReader(responseStr) ) + parser.nextTag() + + val articles = parseXML(parser) + function(articles) + }, { error -> Log.e("XMLLIST", error.toString()) }) - queue.add(stringRequest) - Log.e("XMLLIST", "Adding request to queue from: $url") } private fun parseXML(parser: XmlPullParser): List
{ @@ -56,7 +95,7 @@ internal object Utilities { continue } if (parser.name == "z:row") { - articles.add(parseZROW(parser)) + parseZROW(parser)?.let { articles.add(it) } } else { parseSkip(parser) } @@ -64,16 +103,21 @@ internal object Utilities { return articles } - private fun parseZROW(parser: XmlPullParser): Article { + private fun parseZROW(parser: XmlPullParser): Article? { parser.require(XmlPullParser.START_TAG, null, "z:row") val title = parser.getAttributeValue(null, "ows_Title") val content = parser.getAttributeValue(null, "ows_Body") val date = parser.getAttributeValue(null, "ows_Created") val author = parser.getAttributeValue(null, "ows_Autor2") + val category = parser.getAttributeValue(null, "ows_Kategorie") parser.nextTag() - parser.require(XmlPullParser.END_TAG, null, "link") + parser.require(XmlPullParser.END_TAG, null, "z:row") + + if(title == null || content == null || date == null || author == null || category == null){ + return null + } - return Article(title, content, date, author) + return Article(title, content, date, author, category) } private fun parseSkip(parser: XmlPullParser) { @@ -88,4 +132,49 @@ internal object Utilities { } } } + + fun sendNotification(context: Context?, article: Article, id:Int) { + val intent = Intent(context, MainActivity::class.java).apply { + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + } + val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, 0) + + var builder = NotificationCompat.Builder(context!!, context.getString(R.string.channel_id)) + .setSmallIcon(R.drawable.ic_stat_name) + .setContentTitle(article.title) + .setStyle(NotificationCompat.BigTextStyle() + .bigText(HtmlCompat.fromHtml(article.content, HtmlCompat.FROM_HTML_MODE_COMPACT))) + .setContentIntent(pendingIntent) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setAutoCancel(true) + + with(NotificationManagerCompat.from(context)) { + // notificationId is a unique int for each notification that you must define + notify(id, builder.build()) + } + + } + + fun createNotificationChannel(context: Context?){ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val name = context?.getString(R.string.channel_name) + val descriptionText = context?.getString(R.string.channel_description) + val importance = NotificationManager.IMPORTANCE_DEFAULT + val channel = NotificationChannel(context?.getString(R.string.channel_id), name, importance).apply { + description = descriptionText + } + val notificationManager: NotificationManager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + notificationManager.createNotificationChannel(channel) + } + } + + fun getLatestRelevantArticle(articles: List
): Article? { + val sortedArticles = articles.sortedByDescending { it.date } + for (article in sortedArticles){ + if( article.category == "Lehre" || article.category == "Prüfung" || article.category == "Sonstiges"){ + return article + } + } + return null + } } diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/ItemArticleAdapter.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/ItemArticleAdapter.kt index ed6d1fa..8beabbf 100644 --- a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/ItemArticleAdapter.kt +++ b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/ItemArticleAdapter.kt @@ -1,26 +1,38 @@ package com.nareshkumarrao.eiweblog.ui.main +import android.os.Build +import android.text.Html +import android.text.util.Linkify import android.view.LayoutInflater import android.view.ViewGroup import android.widget.TextView +import androidx.core.text.HtmlCompat import androidx.recyclerview.widget.RecyclerView import com.nareshkumarrao.eiweblog.R +import org.w3c.dom.Text -data class Article(val title: String, val content: String, val date: String, val author: String) +data class Article(val title: String, val content: String, val date: String, val author: String, val category: String) class ItemArticleAdapter(private val articles: List
) : RecyclerView.Adapter() { inner class ViewHolder(inflater: LayoutInflater, parent: ViewGroup) : RecyclerView.ViewHolder(inflater.inflate(R.layout.item_article, parent, false)) { private var title: TextView? = null private var content: TextView? = null + private var date: TextView? = null + private var author: TextView? = null init { title = itemView.findViewById(R.id.titleText) content = itemView.findViewById(R.id.contentText) + date = itemView.findViewById(R.id.dateText) + author = itemView.findViewById(R.id.authorText) } fun bind(article: Article) { title?.text = article.title - content?.text = article.content + content?.text = HtmlCompat.fromHtml(article.content, HtmlCompat.FROM_HTML_MODE_COMPACT) + content?.let { Linkify.addLinks(it, Linkify.WEB_URLS) }; + author?.text = article.author + date?.text = article.date } } diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsFragment.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsFragment.kt index 59c49c0..8383f51 100644 --- a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsFragment.kt +++ b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsFragment.kt @@ -7,11 +7,23 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.nareshkumarrao.eiweblog.R +import com.nareshkumarrao.eiweblog.Utilities + +class SectionsFragment() : Fragment() { + + private var swipeRefreshLayout: SwipeRefreshLayout? = null -class SectionsFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_sections, container, false) + val rootView = inflater.inflate(R.layout.fragment_sections, container, false) + + this.swipeRefreshLayout = rootView.findViewById(R.id.sectionsSwipeRefresh) + this.swipeRefreshLayout?.setOnRefreshListener { + Utilities.fetchWeblogXML(this.context, ::updateView) + } + + return rootView } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -20,12 +32,36 @@ class SectionsFragment : Fragment() { layoutManager = LinearLayoutManager(activity) adapter = ItemArticleAdapter(listOf()) } + Utilities.weblogList(this.context, ::updateView) + } + companion object { + private const val ARG_SECTION_NAME = "section_title" + + @JvmStatic + fun newInstance(title: String): SectionsFragment { + return SectionsFragment().apply { + arguments = Bundle().apply { + putString(ARG_SECTION_NAME, title) + } + } + } } - fun updateView(get_articles: List
){ + + private fun updateView(get_articles: List
){ + this.swipeRefreshLayout?.isRefreshing=false + var articles: MutableList
= mutableListOf() + val title = arguments?.getString(ARG_SECTION_NAME) ?: return + for (article in get_articles){ + if(article.category == title){ + articles.add(article) + } + } + articles.sortByDescending { it.date } + view?.findViewById(R.id.sectionsRecylerView)?.apply { layoutManager = LinearLayoutManager(activity) - adapter = ItemArticleAdapter(get_articles) + adapter = ItemArticleAdapter(articles) } } } \ No newline at end of file diff --git a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsPagerAdapter.kt b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsPagerAdapter.kt index 74bcc15..c3a230a 100644 --- a/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsPagerAdapter.kt +++ b/app/src/main/java/com/nareshkumarrao/eiweblog/ui/main/SectionsPagerAdapter.kt @@ -16,7 +16,7 @@ class SectionsPagerAdapter(private val context: Context, fm: FragmentManager) : FragmentPagerAdapter(fm) { override fun getItem(position: Int): Fragment { - return SectionsFragment() + return SectionsFragment.newInstance( context.resources.getString(TAB_TITLES[position]) ) } override fun getPageTitle(position: Int): CharSequence? { diff --git a/app/src/main/res/drawable-hdpi/ic_stat_name.png b/app/src/main/res/drawable-hdpi/ic_stat_name.png new file mode 100644 index 0000000000000000000000000000000000000000..d4cbf09eb529fe7cba47fb486eede62866bc4a33 GIT binary patch literal 645 zcmV;00($+4P)ulP1z`;2(z@cQnONHbo?Wq_OH2SHKm>Sy zu;0tQVk4kK%nJx<_+ug33OI37LWdZWs6@u@!-hioJ@N~OBf@xeWwI&AV5~BYSAZta z2Hc>T{c_L(TGRayV@hlXGs!b@T*DS~GX4nO!3{tE8@S~$e+8plD`F49w1u58Z55~p z^3%A-V(uP%f;q4UR=_;i2g_gqjBsr=#c$c91o;iWil8Y;Y<u=uGiTcToJS&AcSf zNfkp;D|h`sP$ONsVlyupJ*r|z>QR3xL7COByER3e!_fp4UQ=+#I+6lLaR;%rE}Q@T~r22=sM{a z^F~m_wY3zq;nZak)Z-dY*^JYm)^+Ub`GwY<9{Y5O@qzIoNpK4sF*$C712AY3v}ThS zpH&lMs?zZt)YmK@_lEu*`xEJ0mQm?26<4omya)91PA$c>&QMruS$wMv>$^dhqvC3~ zKga&f_2b`N&@8U7V_Cn#nndlfR=Kl!$v2(6J_paBn6_t-%|lUg$WqoGiWXnX&*yUX fp3=FNYc}l*(-yG;PB@{-00000NkvXXu0mjf`*|%| literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_stat_name.png b/app/src/main/res/drawable-mdpi/ic_stat_name.png new file mode 100644 index 0000000000000000000000000000000000000000..5464f21e47f081586e592c11f0892e0d175d2848 GIT binary patch literal 360 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 o>8R7?oRThJ&(IPXXc#U z*_qkhoE%G*ELpN-$&w{YmMmGaWXX~xONtVSL@r?x;Xc9|!d5~v;a9>*LMNdIf7@`r z8TYLv+>hVqT4|;){DFkuAYeD7et(RxiSPhnn3e9?!j2Kj3D1f1-zG9orwKa zF8Dk`4WR|X=~hh!yZ$`h;8wzJLLFflVF96xP(ru{f6H)QU0;v;ThH+Y9YFng+4#mU zB^=fWrIy_{8f|z#hxPO$OhjGkt^X&9A`au8ST+cMCShNawt5fYP7muIL|9DtEXkLl z_$rNZbEBG&F7eRnxPdUuXMT!NZ>Qj=8%!>hH4CVTfu@(>OAS=UzwYYHL#e!m{S~NX#bFzTow%|?C z(x5tC?$6(q?nn_M<{Jnj#Q z>kAOj=52qmVG5AJ{tm)$2XZJD&oSFC1#D-PHaYlx&tXr_^+AYWi#P(Ce*hHpRliQC*cED#z#2Ul|lgn2tSLueE8zHa8XWs*? zBRtEZa~qNgl+J&sF+<0@lua2A+Iyt{o=IGiVFmc<3u@Bz0i#^XriA;Jyix!c+H`{z zaFG~LCg5L+xp=1O+(T@?fYb`e(`3B;;KUi{_ZQ%0AJ99vQ`W?5xUL*@j}l&nK>sE@ zj!0S;ypOf$56%EI#TT?u(+6B- zf-fj4-q3xTKA^xwdA@l=qY@9801J!LTP|LxNq)rxaw8HEi(#1pPDh;14fZV}hRS$K z#|}dk@QP-#_zV~2`4baHWnN`P?1h{74ZNog)^+95L1x*jbW6t~G~Ab=f>mcxD)w zk~8J2A}V}2Q@$=NjLEekI-<7vAXWtE2<2K4Yq+JPKU9pCW_{$i!Ep|GUWUg zz|QXxZT@nTJF$7l7~olKL*XzB`^vd(q3&?gc)-EpcmrEI`ig*gD*_+UTsvCxz}E>k zZjh^|Z`Q2l-i=k>qq(UAcDzWne?X8cm2$ei^-c$gD>e^1>v0$Skyb$T + + + diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml new file mode 100644 index 0000000..4efb1cf --- /dev/null +++ b/app/src/main/res/layout/activity_about.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + +