Recently Written · git

subread-overlay

Shows the lines of an .srt over any Android media player, in time with it. Tap a word to look it up.

git clone https://github.com/equwal/subread-overlay

Log | Files | Refs


app/src/main/kotlin/space/subread/overlay/Store.kt (3503 bytes)

1 package space.subread.overlay
2 
3 import android.content.ComponentName
4 import android.content.Context
5 import android.content.Intent
6 import android.net.Uri
7 import androidx.core.content.edit
8 import androidx.core.net.toUri
9 
10 /** What the user chose. It stays when the app stops. */
11 class Store(context: Context) {
12 
13     private val prefs = context.getSharedPreferences("overlay", Context.MODE_PRIVATE)
14 
15     var subtitles: Uri?
16         get() = prefs.getString("subtitles", null)?.toUri()
17         set(value) = prefs.edit {
18             putString("subtitles", value?.toString())
19             // The offset belongs to one file and its media. Another file starts at zero.
20             putLong("offset", 0)
21         }
22 
23     var subtitlesName: String?
24         get() = prefs.getString("subtitles_name", null)
25         set(value) = prefs.edit { putString("subtitles_name", value) }
26 
27     var offsetMs: Long
28         get() = prefs.getLong("offset", 0)
29         set(value) = prefs.edit { putLong("offset", value) }
30 
31     var textSizeSp: Float
32         get() = prefs.getFloat("text_size", 22f)
33         set(value) = prefs.edit { putFloat("text_size", value.coerceIn(12f, 60f)) }
34 
35     /** How much of the player shows through the panel, 0 to 90 percent. The text stays black. */
36     var transparencyPercent: Int
37         get() = prefs.getInt("transparency", 30)
38         set(value) = prefs.edit { putInt("transparency", value.coerceIn(0, 90)) }
39 
40     /** True: the panel shows the line before and the line after the line of now too. */
41     var linesAround: Boolean
42         get() = prefs.getBoolean("lines_around", false)
43         set(value) = prefs.edit { putBoolean("lines_around", value) }
44 
45     /** Where the panel is, in pixels from the top left of the screen. */
46     var x: Int
47         get() = prefs.getInt("x", 0)
48         set(value) = prefs.edit { putInt("x", value) }
49 
50     var y: Int
51         get() = prefs.getInt("y", 200)
52         set(value) = prefs.edit { putInt("y", value) }
53 
54     /** True when the user wants the panel on the screen. The listener shows it again after a restart. */
55     var shown: Boolean
56         get() = prefs.getBoolean("shown", false)
57         set(value) = prefs.edit { putBoolean("shown", value) }
58 
59     /** The app that gets the word. Null: Android asks each time. */
60     var dictionary: ComponentName?
61         get() = prefs.getString("dictionary", null)?.let(ComponentName::unflattenFromString)
62         set(value) = prefs.edit { putString("dictionary", value?.flattenToString()) }
63 }
64 
65 /** Sends a word to a dictionary, a translator or a flash card app. */
66 object Lookup {
67 
68     /** The intent that each app with "process text" in its manifest takes. It is what a text selection menu sends. */
69     fun probe(): Intent = Intent(Intent.ACTION_PROCESS_TEXT).setType("text/plain")
70 
71     /** The share sheet of Android: each app that takes a text, also one without "process text". */
72     fun share(word: String): Intent =
73         Intent.createChooser(Intent(Intent.ACTION_SEND).setType("text/plain").putExtra(Intent.EXTRA_TEXT, word), null)
74             .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
75 
76     fun intent(word: String, chosen: ComponentName?): Intent {
77         val send = probe()
78             .putExtra(Intent.EXTRA_PROCESS_TEXT, word)
79             .putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, true)
80         val target = if (chosen != null) send.setComponent(chosen) else Intent.createChooser(send, null)
81         // The panel is not an activity.
82         return target.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
83     }
84 }