Ver código fonte

added programme fragment with simple RecyclerView

yattoz 4 anos atrás
pai
commit
c20727fca7

+ 16 - 2
app/src/main/java/fr/forum_thalie/tsumugi/planning/Planning.kt Ver arquivo

@@ -3,15 +3,17 @@ package fr.forum_thalie.tsumugi.planning
3 3
 import android.content.Context
4 4
 import androidx.lifecycle.MutableLiveData
5 5
 import fr.forum_thalie.tsumugi.Async
6
+import fr.forum_thalie.tsumugi.weekdays
6 7
 import org.json.JSONObject
7 8
 import java.io.IOException
8 9
 import java.net.URL
9 10
 
10 11
 class Planning {
11 12
 
12
-    private val programmes: ArrayList<Programme> = ArrayList()
13
+    val programmes: ArrayList<Programme> = ArrayList()
13 14
     private var regularProgramme: String? = null
14 15
     val currentProgramme: MutableLiveData<String> = MutableLiveData()
16
+    val isProgrammeUpdated: MutableLiveData<Boolean> = MutableLiveData()
15 17
 
16 18
     private fun findCurrentProgramme(): String
17 19
     {
@@ -59,7 +61,18 @@ class Planning {
59 61
                 for (i in 0 until programList.length())
60 62
                 {
61 63
                     val item = programList[i] as JSONObject
62
-                    val periodicity = item.getInt("periodicity")
64
+                    var periodicityDec = item.getInt("periodicity")
65
+                    var periodicity = 0b0000000
66
+                    var po = 1000000
67
+                    for (j in 0 until weekdays.size)
68
+                    {
69
+                        if (periodicityDec / (po) > 0)
70
+                        {
71
+                            periodicityDec -= po
72
+                            periodicity += 1 shl (weekdays.size-1 - j)
73
+                        }
74
+                        po /= 10
75
+                    }
63 76
                     val hourBeginS = item.getString("hour_begin").split(":")
64 77
                     val hourBegin = hourBeginS.first().toInt()*60 + hourBeginS.last().toInt()
65 78
                     val hourEndS = item.getString("hour_end").split(":")
@@ -70,6 +83,7 @@ class Planning {
70 83
             }
71 84
             if (result.has("regular_programme"))
72 85
                 regularProgramme = result.getString("regular_programme")
86
+            isProgrammeUpdated.value = true
73 87
         }
74 88
         Async(scrape, post)
75 89
     }

+ 25 - 3
app/src/main/java/fr/forum_thalie/tsumugi/planning/Programme.kt Ver arquivo

@@ -2,11 +2,13 @@ package fr.forum_thalie.tsumugi.planning
2 2
 
3 3
 import android.util.Log
4 4
 import fr.forum_thalie.tsumugi.tag
5
+import fr.forum_thalie.tsumugi.weekdays
5 6
 import java.util.*
7
+import kotlin.collections.ArrayList
6 8
 
7 9
 class Programme (val title: String, private val periodicity: Int, private val hourBegin: Int, private val hourEnd: Int) {
8 10
     fun isCurrent(): Boolean {
9
-        val now = Calendar.getInstance()
11
+        val now = Calendar.getInstance(TimeZone.getTimeZone("GMT+1"))
10 12
         val currentDay =
11 13
             if (now.get(Calendar.DAY_OF_WEEK) - 1 == 0) 6 else now.get(Calendar.DAY_OF_WEEK) - 2
12 14
         // 0 (Monday) to 5 (Saturday) + 6 (Sunday)
@@ -16,9 +18,9 @@ class Programme (val title: String, private val periodicity: Int, private val ho
16 18
         // OR
17 19
         // - Yesterday is flagged in the "periodicity" bit array AND the program does span over 2 days (night programs).
18 20
         // We'll check a after this whether the current hour is within the span.
19
-        val isToday: Boolean = ((((1000000 shr currentDay) and (periodicity)) != 0))
21
+        val isToday: Boolean = (((0b1000000 shr currentDay) and (periodicity)) != 0)
20 22
         val isSpanningOverNight =
21
-            (((1000000 shr ((currentDay - 1) % 7) and (periodicity)) != 0) && hourEnd < hourBegin)
23
+            (((0b1000000 shr ((currentDay - 1) % 7) and (periodicity)) != 0) && hourEnd < hourBegin)
22 24
 
23 25
         Log.d(tag, "$title is today: $isToday or spanning $isSpanningOverNight")
24 26
         // shr = shift-right. It's a binary mask.
@@ -44,6 +46,26 @@ class Programme (val title: String, private val periodicity: Int, private val ho
44 46
         return "Title: $title, time info (periodicity, begin, end): $periodicity, $hourBegin, $hourEnd"
45 47
     }
46 48
 
49
+    fun begin(): String {
50
+        return "%02d:%02d".format(hourBegin/60, hourBegin%60)
51
+    }
52
+
53
+    fun end(): String {
54
+        return "%02d:%02d".format(hourEnd/60, hourEnd%60)
55
+    }
56
+
57
+    fun days(): String {
58
+        val res = ArrayList<String>()
59
+        for (i in 0 until weekdays.size) {
60
+            if (((0b1000000 shr i) and (periodicity)) != 0)
61
+            {
62
+                res.add(weekdays[i])
63
+            }
64
+
65
+        }
66
+        return res.toString().drop(1).dropLast(1) //  drop '[' and ']'
67
+    }
68
+
47 69
     init {
48 70
         Log.d(tag, this.toString())
49 71
     }

+ 1 - 1
app/src/main/java/fr/forum_thalie/tsumugi/ui/nowplaying/NowPlayingFragment.kt Ver arquivo

@@ -54,7 +54,7 @@ class NowPlayingFragment : Fragment() {
54 54
 
55 55
         // Note: these values are not used in the generic app, but if you want to, you can use them.
56 56
         val songTitleNextText: TextView = root.findViewById(R.id.text_song_title_next)
57
-        val songArtistNextText: TextView = root.findViewById(R.id.text_song_artist_next)
57
+        //val songArtistNextText: TextView = root.findViewById(R.id.text_song_artist_next)
58 58
 
59 59
         /*
60 60
         val streamerNameText : TextView = root.findViewById(R.id.streamerName)

+ 1 - 2
app/src/main/java/fr/forum_thalie/tsumugi/ui/songs/SongsFragment.kt Ver arquivo

@@ -10,6 +10,7 @@ import androidx.fragment.app.FragmentPagerAdapter
10 10
 import androidx.viewpager.widget.ViewPager
11 11
 import com.google.android.material.tabs.TabLayout
12 12
 import fr.forum_thalie.tsumugi.R
13
+import fr.forum_thalie.tsumugi.ui.songs.programme.ProgrammeFragment
13 14
 import fr.forum_thalie.tsumugi.ui.songs.queuelp.LastPlayedFragment
14 15
 
15 16
 class SongsFragment : Fragment() {
@@ -32,14 +33,12 @@ class SongsFragment : Fragment() {
32 33
         // You can add more fragments to the adapter, to display more information (for example with R/a/dio, queue, request, faves...)
33 34
         adapter.addFragment(ProgrammeFragment.newInstance(), getString(R.string.programme))
34 35
 
35
-
36 36
         viewPager.adapter = adapter
37 37
 
38 38
         val tabLayout : TabLayout = root.findViewById(R.id.tabLayout)
39 39
         tabLayout.setupWithViewPager(viewPager)
40 40
         Log.d(tag, "SongFragment view created")
41 41
 
42
-
43 42
         return root
44 43
     }
45 44
 

+ 61 - 0
app/src/main/java/fr/forum_thalie/tsumugi/ui/songs/programme/ProgrammeAdapter.kt Ver arquivo

@@ -0,0 +1,61 @@
1
+package fr.forum_thalie.tsumugi.ui.songs.programme
2
+
3
+import android.annotation.SuppressLint
4
+import android.util.Log
5
+import android.view.LayoutInflater
6
+import android.view.ViewGroup
7
+import android.widget.TextView
8
+import androidx.constraintlayout.widget.ConstraintLayout
9
+import androidx.recyclerview.widget.RecyclerView
10
+import fr.forum_thalie.tsumugi.R
11
+import fr.forum_thalie.tsumugi.colorBlue
12
+import fr.forum_thalie.tsumugi.colorWhited
13
+import fr.forum_thalie.tsumugi.planning.Programme
14
+import fr.forum_thalie.tsumugi.tag
15
+import kotlinx.android.synthetic.main.programme_view.view.*
16
+import kotlinx.android.synthetic.main.song_view.view.*
17
+
18
+class ProgrammeAdapter(private val dataSet: ArrayList<Programme>
19
+    /*,
20
+    context: Context,
21
+    resource: Int,
22
+    objects: Array<out Song>*/
23
+) : RecyclerView.Adapter<ProgrammeAdapter.MyViewHolder>() /*ArrayAdapter<Song>(context, resource, objects)*/ {
24
+
25
+    class MyViewHolder(view: ConstraintLayout) : RecyclerView.ViewHolder(view)
26
+
27
+    // Create new views (invoked by the layout manager)
28
+    override fun onCreateViewHolder(parent: ViewGroup,
29
+                                    viewType: Int): MyViewHolder {
30
+        // create a new view
31
+        val view = LayoutInflater.from(parent.context)
32
+            .inflate(R.layout.programme_view, parent, false) as ConstraintLayout
33
+        return MyViewHolder(view)
34
+    }
35
+
36
+    // Replace the contents of a view (invoked by the layout manager)
37
+    @SuppressLint("SetTextI18n")
38
+    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
39
+        val programmeStart = holder.itemView.findViewById<TextView>(R.id.programme_start)
40
+        val programmeEnd = holder.itemView.findViewById<TextView>(R.id.programme_end)
41
+        val programmeName = holder.itemView.findViewById<TextView>(R.id.programme_name)
42
+        val programmeDays = holder.itemView.findViewById<TextView>(R.id.programme_days)
43
+
44
+        programmeStart.text = dataSet[position].begin()
45
+        programmeName.text = dataSet[position].title
46
+        programmeEnd.text = dataSet[position].end()
47
+        programmeDays.text = dataSet[position].days()
48
+    }
49
+
50
+    // Return the size of your dataset (invoked by the layout manager)
51
+    override fun getItemCount() = dataSet.size
52
+
53
+
54
+    /*
55
+    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
56
+        // create a new view
57
+        val view = LayoutInflater.from(parent.context)
58
+            .inflate(R.layout.song_view, parent, false) as ConstraintLayout
59
+    }
60
+    */
61
+}

app/src/main/java/fr/forum_thalie/tsumugi/ui/songs/ProgrammeFragment.kt → app/src/main/java/fr/forum_thalie/tsumugi/ui/songs/programme/ProgrammeFragment.kt Ver arquivo

@@ -1,13 +1,15 @@
1
-package fr.forum_thalie.tsumugi.ui.songs
1
+package fr.forum_thalie.tsumugi.ui.songs.programme
2 2
 
3 3
 import android.os.Bundle
4 4
 import android.view.LayoutInflater
5 5
 import android.view.View
6 6
 import android.view.ViewGroup
7 7
 import androidx.fragment.app.Fragment
8
+import androidx.lifecycle.Observer
8 9
 import androidx.recyclerview.widget.LinearLayoutManager
9 10
 import androidx.recyclerview.widget.RecyclerView
10 11
 import fr.forum_thalie.tsumugi.R
12
+import fr.forum_thalie.tsumugi.planning.Planning
11 13
 import fr.forum_thalie.tsumugi.playerstore.PlayerStore
12 14
 import fr.forum_thalie.tsumugi.ui.songs.queuelp.LastPlayedFragment
13 15
 import fr.forum_thalie.tsumugi.ui.songs.queuelp.SongAdaptater
@@ -24,34 +26,30 @@ class ProgrammeFragment  : Fragment() {
24 26
     ): View? {
25 27
         // Inflate the layout for this fragment
26 28
         val root = inflater.inflate(R.layout.fragment_programme, container, false)
27
-
28
-        /*
29 29
         viewManager = LinearLayoutManager(context)
30
-        viewAdapter = SongAdaptater(PlayerStore.instance.lp)
31
-
32
-        recyclerView = root.findViewById<RecyclerView>(R.id.queue_lp_recycler).apply {
30
+        viewAdapter = ProgrammeAdapter(Planning.instance.programmes)
31
+        recyclerView = root.findViewById<RecyclerView>(R.id.programme_recycler).apply {
33 32
             // use this setting to improve performance if you know that changes
34 33
             // in content do not change the layout size of the RecyclerView
35 34
             setHasFixedSize(true)
36
-
37
-            // use a linear layout manager
38 35
             layoutManager = viewManager
39
-
40
-            // specify an viewAdapter (see also next example)
41 36
             adapter = viewAdapter
42 37
         }
43
-
44
-         */
45
-
38
+        Planning.instance.isProgrammeUpdated.observeForever(isProgrammeUpdatedObserver)
46 39
         return root
47 40
     }
48 41
 
42
+    private val isProgrammeUpdatedObserver = Observer<Boolean> {
43
+        viewAdapter.notifyDataSetChanged()
44
+    }
45
+
49 46
     override fun onDestroyView() {
50 47
         super.onDestroyView()
48
+        Planning.instance.isProgrammeUpdated.removeObserver(isProgrammeUpdatedObserver)
51 49
     }
52 50
 
53 51
     companion object {
54 52
         @JvmStatic
55
-        fun newInstance() = LastPlayedFragment()
53
+        fun newInstance() = ProgrammeFragment()
56 54
     }
57 55
 }

+ 2 - 0
app/src/main/java/fr/forum_thalie/tsumugi/ui/songs/queuelp/SongAdaptater.kt Ver arquivo

@@ -2,6 +2,7 @@ package fr.forum_thalie.tsumugi.ui.songs.queuelp
2 2
 
3 3
 import android.annotation.SuppressLint
4 4
 import android.graphics.Color
5
+import android.util.Log
5 6
 import android.view.LayoutInflater
6 7
 import android.view.ViewGroup
7 8
 import androidx.constraintlayout.widget.ConstraintLayout
@@ -11,6 +12,7 @@ import fr.forum_thalie.tsumugi.R
11 12
 import fr.forum_thalie.tsumugi.colorBlue
12 13
 import fr.forum_thalie.tsumugi.colorWhited
13 14
 import fr.forum_thalie.tsumugi.playerstore.Song
15
+import fr.forum_thalie.tsumugi.tag
14 16
 import kotlinx.android.synthetic.main.song_view.view.*
15 17
 import kotlin.collections.ArrayList
16 18
 

+ 2 - 2
app/src/main/res/layout/fragment_last_played.xml Ver arquivo

@@ -1,12 +1,12 @@
1 1
 <?xml version="1.0" encoding="utf-8"?>
2
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2
+<LinearLayout
3
+    xmlns:android="http://schemas.android.com/apk/res/android"
3 4
     xmlns:tools="http://schemas.android.com/tools"
4 5
     android:layout_width="match_parent"
5 6
     android:layout_height="match_parent"
6 7
     android:layout_margin="8dp"
7 8
     tools:context=".ui.songs.queuelp.LastPlayedFragment">
8 9
 
9
-    <!-- TODO: Update blank fragment layout -->
10 10
     <androidx.recyclerview.widget.RecyclerView
11 11
         android:layout_width="match_parent"
12 12
         android:layout_height="match_parent"

+ 16 - 4
app/src/main/res/layout/fragment_programme.xml Ver arquivo

@@ -1,7 +1,19 @@
1 1
 <?xml version="1.0" encoding="utf-8"?>
2
-<androidx.constraintlayout.widget.ConstraintLayout
2
+<LinearLayout
3 3
     xmlns:android="http://schemas.android.com/apk/res/android"
4
-    android:orientation="vertical" android:layout_width="match_parent"
5
-    android:layout_height="match_parent">
4
+    xmlns:tools="http://schemas.android.com/tools"
5
+    android:layout_width="match_parent"
6
+    android:layout_height="match_parent"
7
+    android:layout_margin="8dp"
8
+    tools:context=".ui.songs.programme.ProgrammeFragment">
6 9
 
7
-</androidx.constraintlayout.widget.ConstraintLayout>
10
+    <androidx.recyclerview.widget.RecyclerView
11
+        android:layout_width="match_parent"
12
+        android:layout_height="match_parent"
13
+        android:id="@+id/programme_recycler"
14
+        android:scrollbars="vertical"
15
+        >
16
+
17
+    </androidx.recyclerview.widget.RecyclerView>
18
+
19
+</LinearLayout>

+ 52 - 0
app/src/main/res/layout/programme_view.xml Ver arquivo

@@ -0,0 +1,52 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<androidx.constraintlayout.widget.ConstraintLayout
3
+    xmlns:android="http://schemas.android.com/apk/res/android"
4
+    xmlns:app="http://schemas.android.com/apk/res-auto"
5
+    android:orientation="vertical" android:layout_width="match_parent"
6
+    android:layout_height="wrap_content"
7
+    android:layout_margin="8dp">
8
+
9
+    <TextView
10
+        android:id="@+id/programme_days"
11
+        android:layout_width="match_parent"
12
+        android:layout_height="wrap_content"
13
+        app:layout_constraintTop_toTopOf="parent"
14
+        app:layout_constraintStart_toStartOf="parent"
15
+        />
16
+
17
+    <TextView
18
+        android:id="@+id/programme_start"
19
+        android:layout_width="match_parent"
20
+        android:layout_height="wrap_content"
21
+        app:layout_constraintTop_toBottomOf="@id/programme_days"
22
+        app:layout_constraintStart_toStartOf="parent"
23
+        />
24
+
25
+    <TextView
26
+        android:id="@+id/programme_name"
27
+        android:layout_width="match_parent"
28
+        android:layout_height="wrap_content"
29
+        app:layout_constraintTop_toBottomOf="@id/programme_start"
30
+        app:layout_constraintStart_toStartOf="parent"
31
+        />
32
+
33
+    <TextView
34
+        android:id="@+id/programme_end"
35
+        android:layout_width="match_parent"
36
+        android:layout_height="wrap_content"
37
+        app:layout_constraintTop_toBottomOf="@id/programme_name"
38
+        app:layout_constraintStart_toStartOf="parent"
39
+        app:layout_constraintBottom_toBottomOf="parent"
40
+        />
41
+
42
+    <View
43
+        android:id="@+id/divider"
44
+        android:layout_width="match_parent"
45
+        android:layout_height="1dp"
46
+        android:background="?android:attr/listDivider"
47
+        app:layout_constraintTop_toBottomOf="@id/programme_end"
48
+        app:layout_constraintStart_toStartOf="parent"
49
+        app:layout_constraintBottom_toBottomOf="parent"
50
+        app:layout_constraintEnd_toEndOf="parent"/>
51
+
52
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 1
app/src/main/res/values/strings.xml Ver arquivo

@@ -14,7 +14,7 @@
14 14
 
15 15
     <string name="volume">Volume: </string>
16 16
 
17
-    <string name="up_next">Up next:</string>
17
+    <string name="up_next">Émission en cours :</string>
18 18
     <string name="now_streaming">Now streaming</string>
19 19
     <string name="error_webView">Error loading WebView. Try downloading Google Chrome on Google Play, or enabling it if you disabled it.</string>
20 20
     <string name="action_settings">Settings</string>