Quellcode durchsuchen

add news stories (#17)

Ethosa vor 3 Jahren
Ursprung
Commit
e3906a3855

+ 4 - 4
.idea/deploymentTargetDropDown.xml

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="deploymentTargetDropDown">
-    <targetSelectedWithDropDown>
+    <runningDeviceTargetSelectedWithDropDown>
       <Target>
-        <type value="QUICK_BOOT_TARGET" />
+        <type value="RUNNING_DEVICE_TARGET" />
         <deviceKey>
           <Key>
             <type value="VIRTUAL_DEVICE_PATH" />
@@ -11,7 +11,7 @@
           </Key>
         </deviceKey>
       </Target>
-    </targetSelectedWithDropDown>
-    <timeTargetWasSelectedWithDropDown value="2022-04-16T10:11:01.647505700Z" />
+    </runningDeviceTargetSelectedWithDropDown>
+    <timeTargetWasSelectedWithDropDown value="2022-04-17T13:00:34.931527300Z" />
   </component>
 </project>

+ 1 - 0
.idea/misc.xml

@@ -70,6 +70,7 @@
         <entry key="..\:/android projects/KTC/app/src/main/res/layout/layout_lesson.xml" value="0.5" />
         <entry key="..\:/android projects/KTC/app/src/main/res/layout/layout_news.xml" value="0.5" />
         <entry key="..\:/android projects/KTC/app/src/main/res/layout/layout_settings_button.xml" value="0.5" />
+        <entry key="..\:/android projects/KTC/app/src/main/res/layout/layout_story.xml" value="0.33" />
         <entry key="..\:/android projects/KTC/app/src/main/res/layout/layout_teacher.xml" value="0.33" />
         <entry key="..\:/android projects/KTC/app/src/main/res/layout/layout_teacher_lesson.xml" value="0.5" />
         <entry key="..\:/android projects/KTC/app/src/main/res/layout/layout_timetable.xml" value="0.6307053941908713" />

+ 2 - 2
app/build.gradle

@@ -10,8 +10,8 @@ android {
         applicationId "com.ethosa.ktc"
         minSdk 21
         targetSdk 32
-        versionCode 19
-        versionName "0.8.8"
+        versionCode 20
+        versionName "0.8.9"
         ndk {
             abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
         }

+ 23 - 22
app/src/main/AndroidManifest.xml

@@ -14,28 +14,6 @@
         android:theme="@style/Theme.KTC"
         android:usesCleartextTraffic="true"
         tools:targetApi="m">
-        <receiver
-            android:name=".ui.widgets.TeacherTimetableWidget"
-            android:exported="true">
-            <intent-filter>
-                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
-            </intent-filter>
-
-            <meta-data
-                android:name="android.appwidget.provider"
-                android:resource="@xml/teacher_timetable_widget_info" />
-        </receiver>
-        <receiver
-            android:name=".ui.widgets.TimetableWidget"
-            android:exported="true">
-            <intent-filter>
-                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
-            </intent-filter>
-
-            <meta-data
-                android:name="android.appwidget.provider"
-                android:resource="@xml/timetable_widget_info" />
-        </receiver>
 
         <activity
             android:name=".ui.activities.AlbumActivity"
@@ -58,6 +36,29 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+
+        <receiver
+            android:name=".ui.widgets.TeacherTimetableWidget"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+            </intent-filter>
+
+            <meta-data
+                android:name="android.appwidget.provider"
+                android:resource="@xml/teacher_timetable_widget_info" />
+        </receiver>
+        <receiver
+            android:name=".ui.widgets.TimetableWidget"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+            </intent-filter>
+
+            <meta-data
+                android:name="android.appwidget.provider"
+                android:resource="@xml/timetable_widget_info" />
+        </receiver>
     </application>
 
 </manifest>

+ 2 - 3
app/src/main/java/com/ethosa/ktc/Constants.kt

@@ -9,6 +9,8 @@ import androidx.annotation.Keep
 sealed class Constants {
     companion object {
         const val PACKAGE = "com.ethosa.ktc"
+        const val CURRENT_FRAGMENT = "current_fragment"
+        const val VIEWED_NEWS = "viewed_news"
 
         const val TIMETABLE_STATE = "state"
         const val TIMETABLE_BRANCH = "branch"
@@ -16,7 +18,6 @@ sealed class Constants {
         const val TIMETABLE_GROUP_TITLE = "group_title"
         const val TIMETABLE_WEEK = "week"
         const val TIMETABLE_IS_STUDENT = "is_student"
-
         const val TIMETABLE_TEACHER_ID = "teacher_id"
 
         // when google services is available on phone.
@@ -32,7 +33,5 @@ sealed class Constants {
 
         // AppDynamicTheme
         const val CURRENT_THEME = "current_theme"
-
-        const val CURRENT_FRAGMENT = "current_fragment"
     }
 }

+ 9 - 9
app/src/main/java/com/ethosa/ktc/Preferences.kt

@@ -33,10 +33,10 @@ class Preferences(
         var proCollegeUsername = ""
         var proCollegePassword = ""
 
-        // AppDynamicTheme
+        // App
         var currentTheme = "default"
-
         var currentFragment = 0
+        var viewedNews = mutableSetOf<String>()
     }
 
     /**
@@ -59,8 +59,11 @@ class Preferences(
 
             proCollegeUsername = getString(Constants.LOGIN_USERNAME, "")!!
             proCollegePassword = getString(Constants.LOGIN_PASSWORD, "")!!
+
             currentTheme = getString(Constants.CURRENT_THEME, "default")!!
             currentFragment = getInt(Constants.CURRENT_FRAGMENT, 0)
+            viewedNews = getStringSet(Constants.VIEWED_NEWS, mutableSetOf<String>())!!
+            println(viewedNews)
         }
     }
 
@@ -89,15 +92,12 @@ class Preferences(
             .apply()
     }
 
-    fun saveTheme() {
-        preferences.edit()
-            .putString(Constants.CURRENT_THEME, currentTheme)
-            .apply()
-    }
-
-    fun saveFragment() {
+    fun saveApp() {
         preferences.edit()
             .putInt(Constants.CURRENT_FRAGMENT, currentFragment)
+            .putString(Constants.CURRENT_THEME, currentTheme)
+            .putStringSet(Constants.VIEWED_NEWS, viewedNews.toSet())
             .apply()
+        println(viewedNews)
     }
 }

+ 1 - 1
app/src/main/java/com/ethosa/ktc/ui/activities/MainActivity.kt

@@ -39,7 +39,7 @@ class MainActivity : AppCompatActivity() {
         binding.navView.setOnItemSelectedListener {
             Preferences.currentFragment = getMenuNumber(it.itemId)
             navController.navigate(getMenuId())
-            preferences.saveFragment()
+            preferences.saveApp()
             true
         }
         binding.navView.selectedItemId = getMenuId()

+ 8 - 3
app/src/main/java/com/ethosa/ktc/ui/activities/WallPostActivity.kt

@@ -6,6 +6,7 @@ import android.view.MenuItem
 import androidx.appcompat.app.AppCompatActivity
 import androidx.core.text.HtmlCompat
 import com.bumptech.glide.Glide
+import com.ethosa.ktc.Preferences
 import com.ethosa.ktc.R
 import com.ethosa.ktc.college.CollegeApi
 import com.ethosa.ktc.college.CollegeCallback
@@ -67,10 +68,14 @@ class WallPostActivity : AppCompatActivity(), CollegeCallback {
             binding.content.progressBar, "alpha", 1f, 0f
         ).setDuration(500)
         // Fix <img/> tag
-        new.body = new.body.replace(
-            "src=\"/", "src=\"http://www.kansk-tc.ru/"
-        )
+        if (!new.body.startsWith("http"))
+            new.body = new.body.replace(
+                "src=\"/", "src=\"http://www.kansk-tc.ru/"
+            )
         runOnUiThread {
+            // Save as viewed
+            Preferences.viewedNews.add(new.id)
+            Preferences(this).saveApp()
             // Render HTML tags
             binding.content.body.text = HtmlCompat.fromHtml(
                 new.body,

+ 63 - 0
app/src/main/java/com/ethosa/ktc/ui/adapters/NewsStoriesAdapter.kt

@@ -0,0 +1,63 @@
+package com.ethosa.ktc.ui.adapters
+
+import android.content.Intent
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.ethosa.ktc.Preferences
+import com.ethosa.ktc.R
+import com.ethosa.ktc.ui.activities.WallPostActivity
+import com.ethosa.ktc.college.news.News
+import com.ethosa.ktc.databinding.LayoutStoryBinding
+
+/**
+ * Provides RecyclerView.Adapter behavior for news
+ */
+class NewsStoriesAdapter(
+    private var items: List<News>
+) : RecyclerView.Adapter<NewsStoriesAdapter.ViewHolder>(){
+
+    /**
+     * Provides RecyclerView.ViewHolder behavior
+     */
+    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+        var binding = LayoutStoryBinding.bind(view)
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+        return ViewHolder(LayoutInflater.from(parent.context)
+            .inflate(R.layout.layout_story, parent, false)
+        )
+    }
+
+    /**
+     * Loads image if available (without caching)
+     * Loads title, date and wall post text
+     */
+    override fun onBindViewHolder(holder: ViewHolder, pos: Int) {
+        val binding = holder.binding
+        val new = items[pos]
+
+        // Download image and blurs it.
+        Glide.with(binding.root)
+            .load(new.image)
+            .into(binding.story)
+
+        if (new.id in Preferences.viewedNews)
+            binding.story.strokeWidth = 0f
+
+        binding.root.setOnClickListener {
+            // Go to WallPostActivity
+            binding.story.strokeWidth = 0f
+            val intent = Intent(binding.root.context, WallPostActivity::class.java)
+            intent.putExtra("id", new.id)
+            intent.putExtra("title", new.title)
+            intent.putExtra("image", new.image)
+            binding.root.context.startActivity(intent)
+        }
+    }
+
+    override fun getItemCount() = items.size
+}

+ 13 - 4
app/src/main/java/com/ethosa/ktc/ui/fragments/NewsFragment.kt

@@ -7,12 +7,14 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.fragment.app.Fragment
 import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
 import com.ethosa.ktc.Preferences
 import com.ethosa.ktc.college.CollegeApi
 import com.ethosa.ktc.college.CollegeCallback
 import com.ethosa.ktc.college.news.LastNews
 import com.ethosa.ktc.databinding.FragmentNewsBinding
 import com.ethosa.ktc.ui.adapters.NewsAdapter
+import com.ethosa.ktc.ui.adapters.NewsStoriesAdapter
 import com.ethosa.ktc.ui.decoration.SpacingItemDecoration
 import com.google.gson.Gson
 import okhttp3.Call
@@ -33,9 +35,11 @@ class NewsFragment : Fragment(), CollegeCallback {
 
         _binding = FragmentNewsBinding.inflate(inflater, container, false)
         val root: View = binding.root
-        val itemDecoration = SpacingItemDecoration(0, 32)
-        binding.newsContainer.layoutManager = LinearLayoutManager(context)
-        binding.newsContainer.addItemDecoration(itemDecoration)
+        binding.news.layoutManager = LinearLayoutManager(context)
+        binding.news.addItemDecoration(SpacingItemDecoration(0, 32))
+
+        binding.newsStories.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
+        binding.newsStories.addItemDecoration(SpacingItemDecoration(32, 0))
 
         // Fetch last news from college
         CollegeApi.fetchLastNews(this)
@@ -65,7 +69,12 @@ class NewsFragment : Fragment(), CollegeCallback {
         ).setDuration(500)
         activity?.runOnUiThread {
             animate.start()
-            _binding?.newsContainer?.adapter = NewsAdapter(news.anonce + news.news)
+            _binding?.news?.adapter = NewsAdapter(news.anonce + news.news)
+            _binding?.newsStories?.adapter = NewsStoriesAdapter(
+                (news.anonce + news.news)
+                    .filter { it.image != "" }
+                    .sortedBy { it.id in Preferences.viewedNews }
+            )
         }
     }
 }

+ 52 - 8
app/src/main/res/layout/fragment_news.xml

@@ -6,14 +6,57 @@
     android:layout_height="match_parent"
     tools:context=".ui.fragments.NewsFragment">
 
-    <androidx.recyclerview.widget.RecyclerView
-        android:id="@+id/news_container"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
+    <androidx.core.widget.NestedScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:fillViewport="true"
+        tools:layout_editor_absoluteX="-16dp"
+        tools:layout_editor_absoluteY="0dp">
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/news_content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <androidx.constraintlayout.widget.ConstraintLayout
+                android:id="@+id/stories_holder"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent">
+
+                <androidx.recyclerview.widget.RecyclerView
+                    android:id="@+id/news_stories"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    app:layout_constraintBottom_toBottomOf="parent"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toTopOf="parent" />
+            </androidx.constraintlayout.widget.ConstraintLayout>
+
+            <androidx.constraintlayout.widget.ConstraintLayout
+                android:id="@+id/news_container"
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:layout_marginBottom="1dp"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@+id/stories_holder">
+
+                <androidx.recyclerview.widget.RecyclerView
+                    android:id="@+id/news"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toTopOf="parent" />
+            </androidx.constraintlayout.widget.ConstraintLayout>
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+    </androidx.core.widget.NestedScrollView>
 
     <ProgressBar
         android:id="@+id/progress_load"
@@ -25,4 +68,5 @@
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
+
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 24 - 0
app/src/main/res/layout/layout_story.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:paddingTop="2dp"
+    android:paddingBottom="2dp">
+
+    <com.google.android.material.imageview.ShapeableImageView
+        android:id="@+id/story"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:scaleType="centerCrop"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:shapeAppearanceOverlay="@style/roundedImageView"
+        app:srcCompat="@mipmap/ic_launcher"
+        app:strokeColor="?colorPrimary"
+        app:strokeWidth="2dp"
+        tools:ignore="ContentDescription" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 5 - 0
app/src/main/res/values/styles.xml

@@ -46,4 +46,9 @@
     <style name="Theme.KTC.AppWidgetContainer" parent="Theme.KTC.AppWidgetContainerParent">
         <item name="appWidgetPadding">16dp</item>
     </style>
+
+    <style name="roundedImageView">
+        <item name="cornerFamily">rounded</item>
+        <item name="cornerSize">50%</item>
+    </style>
 </resources>