This looks reasonably nice
This commit is contained in:
parent
8e333e55bc
commit
3a2e6cbf57
6 changed files with 244 additions and 157 deletions
|
@ -353,7 +353,7 @@ class Repository(private val sharedPrefs: SharedPreferences, private val databas
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addLastShareTopic(topic: String) {
|
fun addLastShareTopic(topic: String) {
|
||||||
val topics = (getLastShareTopics() + topic).takeLast(LAST_TOPICS_COUNT)
|
val topics = (getLastShareTopics().filterNot { it == topic } + topic).takeLast(LAST_TOPICS_COUNT)
|
||||||
sharedPrefs.edit()
|
sharedPrefs.edit()
|
||||||
.putString(SHARED_PREFS_LAST_TOPICS, topics.joinToString(separator = "\n"))
|
.putString(SHARED_PREFS_LAST_TOPICS, topics.joinToString(separator = "\n"))
|
||||||
.apply()
|
.apply()
|
||||||
|
@ -437,7 +437,7 @@ class Repository(private val sharedPrefs: SharedPreferences, private val databas
|
||||||
const val SHARED_PREFS_UNIFIED_PUSH_BASE_URL = "UnifiedPushBaseURL"
|
const val SHARED_PREFS_UNIFIED_PUSH_BASE_URL = "UnifiedPushBaseURL"
|
||||||
const val SHARED_PREFS_LAST_TOPICS = "LastTopics"
|
const val SHARED_PREFS_LAST_TOPICS = "LastTopics"
|
||||||
|
|
||||||
private const val LAST_TOPICS_COUNT = 5
|
private const val LAST_TOPICS_COUNT = 3
|
||||||
|
|
||||||
const val MUTED_UNTIL_SHOW_ALL = 0L
|
const val MUTED_UNTIL_SHOW_ALL = 0L
|
||||||
const val MUTED_UNTIL_FOREVER = 1L
|
const val MUTED_UNTIL_FOREVER = 1L
|
||||||
|
|
|
@ -13,7 +13,6 @@ import io.heckel.ntfy.R
|
||||||
import io.heckel.ntfy.db.ConnectionState
|
import io.heckel.ntfy.db.ConnectionState
|
||||||
import io.heckel.ntfy.db.Repository
|
import io.heckel.ntfy.db.Repository
|
||||||
import io.heckel.ntfy.db.Subscription
|
import io.heckel.ntfy.db.Subscription
|
||||||
import io.heckel.ntfy.util.isDarkThemeOn
|
|
||||||
import io.heckel.ntfy.util.topicShortUrl
|
import io.heckel.ntfy.util.topicShortUrl
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
|
@ -7,15 +7,15 @@ import android.os.Bundle
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
import android.view.Menu
|
import android.view.*
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import io.heckel.ntfy.R
|
import io.heckel.ntfy.R
|
||||||
import io.heckel.ntfy.app.Application
|
import io.heckel.ntfy.app.Application
|
||||||
|
import io.heckel.ntfy.db.Subscription
|
||||||
import io.heckel.ntfy.msg.ApiService
|
import io.heckel.ntfy.msg.ApiService
|
||||||
import io.heckel.ntfy.util.*
|
import io.heckel.ntfy.util.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -31,6 +31,9 @@ class ShareActivity : AppCompatActivity() {
|
||||||
// Lazy-loaded things from Repository
|
// Lazy-loaded things from Repository
|
||||||
private lateinit var baseUrls: List<String>
|
private lateinit var baseUrls: List<String>
|
||||||
|
|
||||||
|
// Context-dependent things
|
||||||
|
private lateinit var appBaseUrl: String
|
||||||
|
|
||||||
// UI elements
|
// UI elements
|
||||||
private lateinit var menu: Menu
|
private lateinit var menu: Menu
|
||||||
private lateinit var sendItem: MenuItem
|
private lateinit var sendItem: MenuItem
|
||||||
|
@ -43,6 +46,7 @@ class ShareActivity : AppCompatActivity() {
|
||||||
private lateinit var baseUrlLayout: TextInputLayout
|
private lateinit var baseUrlLayout: TextInputLayout
|
||||||
private lateinit var baseUrlText: AutoCompleteTextView
|
private lateinit var baseUrlText: AutoCompleteTextView
|
||||||
private lateinit var useAnotherServerCheckbox: CheckBox
|
private lateinit var useAnotherServerCheckbox: CheckBox
|
||||||
|
private lateinit var lastTopicsList: RecyclerView
|
||||||
private lateinit var progress: ProgressBar
|
private lateinit var progress: ProgressBar
|
||||||
private lateinit var errorText: TextView
|
private lateinit var errorText: TextView
|
||||||
private lateinit var errorImage: ImageView
|
private lateinit var errorImage: ImageView
|
||||||
|
@ -60,6 +64,9 @@ class ShareActivity : AppCompatActivity() {
|
||||||
// Show 'Back' button
|
// Show 'Back' button
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
|
// Context-dependent things
|
||||||
|
appBaseUrl = getString(R.string.app_base_url)
|
||||||
|
|
||||||
// UI elements
|
// UI elements
|
||||||
contentText = findViewById(R.id.share_content_text)
|
contentText = findViewById(R.id.share_content_text)
|
||||||
contentImage = findViewById(R.id.share_content_image)
|
contentImage = findViewById(R.id.share_content_image)
|
||||||
|
@ -73,6 +80,7 @@ class ShareActivity : AppCompatActivity() {
|
||||||
baseUrlText = findViewById(R.id.share_base_url_text)
|
baseUrlText = findViewById(R.id.share_base_url_text)
|
||||||
//baseUrlText.background = topicText.background
|
//baseUrlText.background = topicText.background
|
||||||
useAnotherServerCheckbox = findViewById(R.id.share_use_another_server_checkbox)
|
useAnotherServerCheckbox = findViewById(R.id.share_use_another_server_checkbox)
|
||||||
|
lastTopicsList = findViewById(R.id.share_last_topics)
|
||||||
progress = findViewById(R.id.share_progress)
|
progress = findViewById(R.id.share_progress)
|
||||||
progress.visibility = View.GONE
|
progress.visibility = View.GONE
|
||||||
errorText = findViewById(R.id.share_error_text)
|
errorText = findViewById(R.id.share_error_text)
|
||||||
|
@ -93,6 +101,7 @@ class ShareActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
contentText.addTextChangedListener(textWatcher)
|
contentText.addTextChangedListener(textWatcher)
|
||||||
topicText.addTextChangedListener(textWatcher)
|
topicText.addTextChangedListener(textWatcher)
|
||||||
|
baseUrlText.addTextChangedListener(textWatcher)
|
||||||
|
|
||||||
// Add behavior to "use another" checkbox
|
// Add behavior to "use another" checkbox
|
||||||
useAnotherServerCheckbox.setOnCheckedChangeListener { _, isChecked ->
|
useAnotherServerCheckbox.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
@ -100,9 +109,25 @@ class ShareActivity : AppCompatActivity() {
|
||||||
validateInput()
|
validateInput()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Populate "last topics"
|
||||||
|
val reversedLastTopics = repository.getLastShareTopics().reversed()
|
||||||
|
lastTopicsList.adapter = TopicAdapter(reversedLastTopics) { topicUrl ->
|
||||||
|
try {
|
||||||
|
val (baseUrl, topic) = splitTopicUrl(topicUrl)
|
||||||
|
topicText.text = topic
|
||||||
|
if (baseUrl == appBaseUrl) {
|
||||||
|
useAnotherServerCheckbox.isChecked = false
|
||||||
|
} else {
|
||||||
|
useAnotherServerCheckbox.isChecked = true
|
||||||
|
baseUrlText.setText(baseUrl)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Invalid topicUrl $topicUrl", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add baseUrl auto-complete behavior
|
// Add baseUrl auto-complete behavior
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
val appBaseUrl = getString(R.string.app_base_url)
|
|
||||||
baseUrls = repository.getSubscriptions()
|
baseUrls = repository.getSubscriptions()
|
||||||
.groupBy { it.baseUrl }
|
.groupBy { it.baseUrl }
|
||||||
.map { it.key }
|
.map { it.key }
|
||||||
|
@ -111,14 +136,20 @@ class ShareActivity : AppCompatActivity() {
|
||||||
val activity = this@ShareActivity
|
val activity = this@ShareActivity
|
||||||
activity.runOnUiThread {
|
activity.runOnUiThread {
|
||||||
initBaseUrlDropdown(baseUrls, baseUrlText, baseUrlLayout)
|
initBaseUrlDropdown(baseUrls, baseUrlText, baseUrlLayout)
|
||||||
useAnotherServerCheckbox.isChecked = baseUrls.count() == 1
|
useAnotherServerCheckbox.isChecked = if (reversedLastTopics.isNotEmpty()) {
|
||||||
|
try {
|
||||||
|
val (baseUrl, _) = splitTopicUrl(reversedLastTopics.first())
|
||||||
|
baseUrl != appBaseUrl
|
||||||
|
} catch (_: Exception) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
baseUrls.count() == 1
|
||||||
|
}
|
||||||
|
baseUrlLayout.visibility = if (useAnotherServerCheckbox.isChecked) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate "last topics"
|
|
||||||
val lastTopics = repository.getLastShareTopics()
|
|
||||||
Log.d(TAG, "last topics: $lastTopics")
|
|
||||||
|
|
||||||
// Incoming intent
|
// Incoming intent
|
||||||
val intent = intent ?: return
|
val intent = intent ?: return
|
||||||
if (intent.action != Intent.ACTION_SEND) return
|
if (intent.action != Intent.ACTION_SEND) return
|
||||||
|
@ -284,6 +315,24 @@ class ShareActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TopicAdapter(private val topicUrls: List<String>, val onClick: (String) -> Unit) : RecyclerView.Adapter<TopicAdapter.ViewHolder>() {
|
||||||
|
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.fragment_share_item, viewGroup, false)
|
||||||
|
return ViewHolder(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
|
||||||
|
viewHolder.topicName.text = shortUrl(topicUrls[position])
|
||||||
|
viewHolder.view.setOnClickListener { onClick(topicUrls[position]) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = topicUrls.size
|
||||||
|
|
||||||
|
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
val topicName: TextView = view.findViewById(R.id.share_item_text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "NtfyShareActivity"
|
const val TAG = "NtfyShareActivity"
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,11 @@ fun shortUrl(url: String) = url
|
||||||
.replace("http://", "")
|
.replace("http://", "")
|
||||||
.replace("https://", "")
|
.replace("https://", "")
|
||||||
|
|
||||||
|
fun splitTopicUrl(topicUrl: String): Pair<String, String> {
|
||||||
|
if (topicUrl.lastIndexOf("/") == -1) throw Exception("Invalid argument $topicUrl")
|
||||||
|
return Pair(topicUrl.substringBeforeLast("/"), topicUrl.substringAfterLast("/"))
|
||||||
|
}
|
||||||
|
|
||||||
fun validTopic(topic: String): Boolean {
|
fun validTopic(topic: String): Boolean {
|
||||||
return "[-_A-Za-z0-9]{1,64}".toRegex().matches(topic) // Must match server side!
|
return "[-_A-Za-z0-9]{1,64}".toRegex().matches(topic) // Must match server side!
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<ScrollView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal" android:paddingStart="15dp" android:paddingEnd="15dp" android:paddingTop="10dp" android:paddingBottom="10dp">
|
android:orientation="horizontal" android:paddingStart="15dp" android:paddingEnd="15dp" android:paddingTop="10dp" android:paddingBottom="10dp">
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
|
@ -21,9 +24,9 @@
|
||||||
android:paddingBottom="2dp"
|
android:paddingBottom="2dp"
|
||||||
android:text="@string/share_content_title"
|
android:text="@string/share_content_title"
|
||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Large"
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" android:paddingStart="2dp"/>
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
<com.google.android.material.imageview.ShapeableImageView
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" app:srcCompat="@drawable/ic_cancel_gray_24dp"
|
android:layout_height="wrap_content" app:srcCompat="@drawable/ic_cancel_gray_24dp"
|
||||||
|
@ -75,24 +78,24 @@
|
||||||
android:paddingBottom="3dp"
|
android:paddingBottom="3dp"
|
||||||
android:text="@string/share_topic_title"
|
android:text="@string/share_topic_title"
|
||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Large"
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/share_content_file_box" android:layout_marginTop="15dp" android:paddingStart="2dp"/>
|
app:layout_constraintTop_toBottomOf="@id/share_content_file_box" android:layout_marginTop="15dp"/>
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/share_topic_text"
|
android:id="@+id/share_topic_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" android:hint="@string/add_dialog_topic_name_hint"
|
android:layout_height="wrap_content" android:hint="@string/add_dialog_topic_name_hint"
|
||||||
android:importantForAutofill="no"
|
android:importantForAutofill="no"
|
||||||
android:maxLines="1" android:inputType="text" android:maxLength="64"
|
android:maxLines="1" android:inputType="text|textNoSuggestions" android:maxLength="64"
|
||||||
app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/share_topic_title"/>
|
app:layout_constraintTop_toBottomOf="@id/share_topic_title" android:layout_marginStart="-3dp"/>
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:text="@string/add_dialog_use_another_server"
|
android:text="@string/add_dialog_use_another_server"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" android:id="@+id/share_use_another_server_checkbox"
|
android:layout_height="wrap_content" android:id="@+id/share_use_another_server_checkbox"
|
||||||
android:layout_marginStart="-3dp" app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/share_topic_text"/>
|
app:layout_constraintTop_toBottomOf="@id/share_topic_text" android:paddingTop="-5dp" android:layout_marginTop="-5dp" android:layout_marginStart="-5dp"/>
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.Dense.ExposedDropdownMenu"
|
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.Dense.ExposedDropdownMenu"
|
||||||
android:id="@+id/share_base_url_layout"
|
android:id="@+id/share_base_url_layout"
|
||||||
|
@ -100,29 +103,26 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="0dp"
|
android:layout_margin="0dp"
|
||||||
android:padding="0dp"
|
android:padding="0dp"
|
||||||
android:visibility="gone"
|
android:visibility="visible"
|
||||||
app:endIconMode="custom"
|
app:endIconMode="custom"
|
||||||
app:hintEnabled="false"
|
app:hintEnabled="false"
|
||||||
app:boxBackgroundColor="@null" app:layout_constraintStart_toStartOf="parent"
|
app:boxBackgroundColor="@null"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/share_use_another_server_checkbox">
|
app:layout_constraintTop_toBottomOf="@id/share_use_another_server_checkbox" app:layout_constraintStart_toStartOf="parent" android:layout_marginTop="-5dp">
|
||||||
<AutoCompleteTextView
|
<AutoCompleteTextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/share_base_url_text"
|
android:id="@+id/share_base_url_text"
|
||||||
android:hint="@string/app_base_url"
|
android:hint="@string/app_base_url"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:layout_marginTop="0dp"
|
android:layout_marginTop="-5dp"
|
||||||
android:layout_marginBottom="0dp"
|
android:layout_marginBottom="0dp"
|
||||||
android:inputType="textNoSuggestions"
|
android:inputType="textUri|textNoSuggestions"
|
||||||
android:paddingStart="0dp"
|
android:paddingStart="0dp"
|
||||||
android:paddingEnd="0dp"
|
android:paddingEnd="0dp"
|
||||||
android:paddingTop="5dp"
|
android:paddingTop="5dp"
|
||||||
android:paddingBottom="5dp"
|
android:paddingBottom="5dp"
|
||||||
android:layout_marginStart="4dp"
|
android:layout_marginStart="4dp" android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
/>
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/share_last_title"
|
android:id="@+id/share_last_title"
|
||||||
|
@ -132,13 +132,19 @@
|
||||||
android:paddingBottom="3dp"
|
android:paddingBottom="3dp"
|
||||||
android:text="@string/share_previous_topics"
|
android:text="@string/share_previous_topics"
|
||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Large"
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
android:paddingStart="2dp" app:layout_constraintTop_toBottomOf="@id/share_base_url_layout" app:layout_constraintStart_toStartOf="parent" android:layout_marginTop="15dp"/>
|
app:layout_constraintTop_toBottomOf="@id/share_base_url_layout" app:layout_constraintStart_toStartOf="parent" android:layout_marginTop="15dp"/>
|
||||||
<LinearLayout
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:orientation="vertical"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_height="wrap_content" android:id="@+id/share_last_layout" app:layout_constraintTop_toBottomOf="@id/share_last_title" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" android:layout_marginTop="5dp">
|
android:id="@+id/share_last_topics"
|
||||||
</LinearLayout>
|
app:layout_constraintTop_toBottomOf="@id/share_last_title"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
app:layoutManager="LinearLayoutManager"/>
|
||||||
<TextView
|
<TextView
|
||||||
android:text="Unable to resolve host example.com"
|
android:text="Unable to resolve host example.com"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
@ -148,7 +154,7 @@
|
||||||
android:paddingEnd="4dp"
|
android:paddingEnd="4dp"
|
||||||
android:textAppearance="@style/DangerText"
|
android:textAppearance="@style/DangerText"
|
||||||
app:layout_constraintStart_toEndOf="@id/share_error_image"
|
app:layout_constraintStart_toEndOf="@id/share_error_image"
|
||||||
android:layout_marginTop="10dp" app:layout_constraintTop_toBottomOf="@id/share_last_title"/>
|
android:layout_marginTop="10dp" app:layout_constraintTop_toBottomOf="@id/share_last_topics"/>
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="20dp"
|
android:layout_width="20dp"
|
||||||
android:layout_height="20dp" app:srcCompat="@drawable/ic_error_red_24dp"
|
android:layout_height="20dp" app:srcCompat="@drawable/ic_error_red_24dp"
|
||||||
|
@ -156,4 +162,5 @@
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/share_error_text" android:layout_marginTop="2dp"/>
|
app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/share_error_text" android:layout_marginTop="2dp"/>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
27
app/src/main/res/layout/fragment_share_item.xml
Normal file
27
app/src/main/res/layout/fragment_share_item.xml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?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"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:orientation="horizontal" android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
>
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp" app:srcCompat="@drawable/ic_sms_gray_24dp"
|
||||||
|
android:id="@+id/share_item_image"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/share_item_text"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/share_item_text" android:layout_marginStart="2dp"/>
|
||||||
|
<TextView
|
||||||
|
android:text="ntfy.sh/example"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content" android:id="@+id/share_item_text"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/share_item_image"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
|
android:textColor="?android:attr/textColorPrimary" android:layout_marginTop="7dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="7dp" android:layout_marginStart="4dp"/>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
Loading…
Reference in a new issue