Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 170bdc24 authored by Philipp Heckel's avatar Philipp Heckel
Browse files

Add dialog instead of activity

parent 0c3a14d5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -63,4 +63,5 @@ dependencies {

    // LiveData
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.liveDataVersion"
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}
+0 −17
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2020 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="io.heckel.ntfy">

@@ -36,5 +20,4 @@
        <activity android:name="io.heckel.ntfy.add.AddTopicActivity" />
        <activity android:name="io.heckel.ntfy.detail.DetailActivity" />
    </application>

</manifest>
+80 −0
Original line number Diff line number Diff line
package io.heckel.ntfy

import android.app.AlertDialog
import android.app.Dialog
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.widget.CheckBox
import androidx.fragment.app.DialogFragment
import com.google.android.material.textfield.TextInputEditText

class AddFragment(private val listener: Listener) : DialogFragment() {
    interface Listener {
        fun onAddClicked(topic: String, baseUrl: String)
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return activity?.let {
            // Build root view
            val view = requireActivity().layoutInflater.inflate(R.layout.fragment_add, null)
            val topicNameText = view.findViewById(R.id.add_dialog_topic_text) as TextInputEditText
            val baseUrlText = view.findViewById(R.id.add_dialog_base_url_text) as TextInputEditText
            val useAnotherServerCheckbox = view.findViewById(R.id.add_dialog_use_another_server_checkbox) as CheckBox
            useAnotherServerCheckbox.setOnCheckedChangeListener { buttonView, isChecked ->
                if (isChecked) baseUrlText.visibility = View.VISIBLE
                else baseUrlText.visibility = View.GONE
            }

            // Build dialog
            val alert = AlertDialog.Builder(it)
                .setView(view)
                .setPositiveButton(R.string.add_dialog_button_subscribe) { _, _ ->
                    val topic = topicNameText.text.toString()
                    val baseUrl = if (useAnotherServerCheckbox.isChecked) {
                        baseUrlText.text.toString()
                    } else {
                        getString(R.string.add_dialog_base_url_default)
                    }
                    listener.onAddClicked(topic, baseUrl)
                }
                .setNegativeButton(R.string.add_dialog_button_cancel) { _, _ ->
                    dialog?.cancel()
                }
                .create()

            // Add logic to disable "Subscribe" button on invalid input
            alert.setOnShowListener {
                val dialog = it as AlertDialog

                val subscribeButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE)
                subscribeButton.isEnabled = false

                val textWatcher = object : TextWatcher {
                    override fun afterTextChanged(s: Editable?) {
                        if (useAnotherServerCheckbox.isChecked) {
                            subscribeButton.isEnabled = topicNameText.text.toString().isNotBlank()
                                    && "[-_A-Za-z0-9]+".toRegex().matches(topicNameText.text.toString())
                                    && baseUrlText.text.toString().isNotBlank()
                                    && "^https?://.+".toRegex().matches(baseUrlText.text.toString())
                        } else {
                            subscribeButton.isEnabled = topicNameText.text.toString().isNotBlank()
                                    && "[-_A-Za-z0-9]+".toRegex().matches(topicNameText.text.toString())
                        }
                    }
                    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                        // Nothing
                    }
                    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                        // Nothing
                    }
                }
                topicNameText.addTextChangedListener(textWatcher)
                baseUrlText.addTextChangedListener(textWatcher)
            }

            alert
        } ?: throw IllegalStateException("Activity cannot be null")
    }
}
+10 −20
Original line number Diff line number Diff line
package io.heckel.ntfy

import android.app.Activity
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
@@ -13,17 +12,16 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.recyclerview.widget.RecyclerView
import io.heckel.ntfy.add.AddTopicActivity
import io.heckel.ntfy.data.*
import io.heckel.ntfy.data.Notification
import io.heckel.ntfy.data.Status
import io.heckel.ntfy.data.Subscription
import io.heckel.ntfy.data.topicShortUrl
import io.heckel.ntfy.detail.DetailActivity
import kotlin.random.Random

const val SUBSCRIPTION_ID = "topic_id"
const val TOPIC_NAME = "topic_name"
const val SERVICE_BASE_URL = "base_url"

class MainActivity : AppCompatActivity() {
    private val newSubscriptionActivityRequestCode = 1
class MainActivity : AppCompatActivity(), AddFragment.Listener {
    private val subscriptionViewModel by viewModels<SubscriptionsViewModel> {
        SubscriptionsViewModelFactory()
    }
@@ -64,22 +62,14 @@ class MainActivity : AppCompatActivity() {

    /* Adds topic to topicList when FAB is clicked. */
    private fun fabOnClick() {
        val intent = Intent(this, AddTopicActivity::class.java)
        startActivityForResult(intent, newSubscriptionActivityRequestCode)
        val newFragment = AddFragment(this)
        newFragment.show(supportFragmentManager, "AddFragment")
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, intentData: Intent?) {
        super.onActivityResult(requestCode, resultCode, intentData)

        if (requestCode == newSubscriptionActivityRequestCode && resultCode == Activity.RESULT_OK) {
            intentData?.let { data ->
                val name = data.getStringExtra(TOPIC_NAME) ?: return
                val baseUrl = data.getStringExtra(SERVICE_BASE_URL) ?: return
                val subscription = Subscription(Random.nextLong(), name, baseUrl, Status.CONNECTING, 0)
    override fun onAddClicked(topic: String, baseUrl: String) {
        val subscription = Subscription(Random.nextLong(), topic, baseUrl, Status.CONNECTING, 0)
        subscriptionViewModel.add(subscription)
    }
        }
    }

    private fun displayNotification(n: Notification) {
        val channelId = getString(R.string.notification_channel_id)
+0 −47
Original line number Diff line number Diff line
package io.heckel.ntfy.add

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.textfield.TextInputEditText
import io.heckel.ntfy.R
import io.heckel.ntfy.SERVICE_BASE_URL
import io.heckel.ntfy.TOPIC_NAME

class AddTopicActivity : AppCompatActivity() {
    private lateinit var topicName: TextInputEditText
    private lateinit var baseUrl: TextInputEditText

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.add_topic_layout)

        findViewById<Button>(R.id.subscribe_button).setOnClickListener {
            addTopic()
        }
        topicName = findViewById(R.id.add_topic_name)
        baseUrl = findViewById(R.id.add_topic_base_url)
        baseUrl.setText(R.string.topic_base_url_default_value)
    }

    /* The onClick action for the done button. Closes the activity and returns the new topic name
    and description as part of the intent. If the name or description are missing, the result is set
    to cancelled. */

    private fun addTopic() {
        val resultIntent = Intent()

        // TODO don't allow this

        if (baseUrl.text.isNullOrEmpty()) {
            setResult(Activity.RESULT_CANCELED, resultIntent)
        } else {
            resultIntent.putExtra(TOPIC_NAME, topicName.text.toString())
            resultIntent.putExtra(SERVICE_BASE_URL, baseUrl.text.toString())
            setResult(Activity.RESULT_OK, resultIntent)
        }
        finish()
    }
}
Loading