mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-20 13:33:13 -07:00
Add Manual Consoles on Android
This commit is contained in:
parent
83777c4fa4
commit
6baf8e9c2a
15 changed files with 374 additions and 160 deletions
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="com.metallic.chiaki">
|
package="com.metallic.chiaki">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
@ -11,7 +12,8 @@
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme"
|
||||||
|
tools:ignore="GoogleAppIndexingWarning">
|
||||||
|
|
||||||
<activity android:name=".main.MainActivity"
|
<activity android:name=".main.MainActivity"
|
||||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||||
|
@ -30,11 +32,6 @@
|
||||||
<activity
|
<activity
|
||||||
android:name=".settings.SettingsActivity" />
|
android:name=".settings.SettingsActivity" />
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".TestStartActivity"
|
|
||||||
android:theme="@style/MageTheme"
|
|
||||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"/>
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".regist.RegistActivity"
|
android:name=".regist.RegistActivity"
|
||||||
android:theme="@style/MageTheme"
|
android:theme="@style/MageTheme"
|
||||||
|
@ -45,6 +42,11 @@
|
||||||
android:name=".regist.RegistExecuteActivity"
|
android:name=".regist.RegistExecuteActivity"
|
||||||
android:theme="@style/MageTheme"
|
android:theme="@style/MageTheme"
|
||||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize" />
|
android:configChanges="keyboard|keyboardHidden|orientation|screenSize" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".manualconsole.AddManualConsoleActivity"
|
||||||
|
android:theme="@style/MageTheme"
|
||||||
|
android:configChanges="keyboard|keyboardHidden|orientation|screenSize" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
|
@ -1,86 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Chiaki.
|
|
||||||
*
|
|
||||||
* Chiaki is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Chiaki is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.metallic.chiaki
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Base64
|
|
||||||
import android.view.View
|
|
||||||
import android.view.Window
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.core.content.edit
|
|
||||||
import androidx.core.widget.addTextChangedListener
|
|
||||||
import com.metallic.chiaki.common.Preferences
|
|
||||||
import com.metallic.chiaki.common.ext.RevealActivity
|
|
||||||
import com.metallic.chiaki.lib.ConnectInfo
|
|
||||||
import com.metallic.chiaki.stream.StreamActivity
|
|
||||||
import kotlinx.android.synthetic.main.activity_test_start.*
|
|
||||||
|
|
||||||
class TestStartActivity : AppCompatActivity(), RevealActivity
|
|
||||||
{
|
|
||||||
override val revealIntent: Intent get() = intent
|
|
||||||
override val revealRootLayout: View get() = rootLayout
|
|
||||||
override val revealWindow: Window get() = window
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?)
|
|
||||||
{
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
setContentView(R.layout.activity_test_start)
|
|
||||||
handleReveal()
|
|
||||||
|
|
||||||
val prefs = getPreferences(Context.MODE_PRIVATE)
|
|
||||||
|
|
||||||
hostEditText.setText(prefs.getString("debug_host", ""))
|
|
||||||
registKeyEditText.setText(prefs.getString("debug_regist_key", ""))
|
|
||||||
morningEditText.setText(prefs.getString("debug_morning", ""))
|
|
||||||
|
|
||||||
hostEditText.addTextChangedListener {
|
|
||||||
prefs.edit {
|
|
||||||
putString("debug_host", it?.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
registKeyEditText.addTextChangedListener {
|
|
||||||
prefs.edit {
|
|
||||||
putString("debug_regist_key", it?.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
morningEditText.addTextChangedListener {
|
|
||||||
prefs.edit {
|
|
||||||
putString("debug_morning", it?.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
startButton.setOnClickListener {
|
|
||||||
val registKeyBase = registKeyEditText.text.toString().toByteArray(Charsets.US_ASCII)
|
|
||||||
val registKey = registKeyBase + ByteArray(0x10 - registKeyBase.size) { 0 }
|
|
||||||
val morning = Base64.decode(morningEditText.text.toString(), Base64.DEFAULT)
|
|
||||||
val connectInfo = ConnectInfo(hostEditText.text.toString(),
|
|
||||||
registKey,
|
|
||||||
morning,
|
|
||||||
Preferences(this).videoProfile)
|
|
||||||
|
|
||||||
Intent(this, StreamActivity::class.java).let {
|
|
||||||
it.putExtra(StreamActivity.EXTRA_CONNECT_INFO, connectInfo)
|
|
||||||
startActivity(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,7 +18,6 @@
|
||||||
package com.metallic.chiaki.main
|
package com.metallic.chiaki.main
|
||||||
|
|
||||||
import android.app.ActivityOptions
|
import android.app.ActivityOptions
|
||||||
import android.app.AlertDialog
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
|
@ -29,7 +28,6 @@ import androidx.lifecycle.ViewModelProviders
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.metallic.chiaki.R
|
import com.metallic.chiaki.R
|
||||||
import com.metallic.chiaki.TestStartActivity
|
|
||||||
import com.metallic.chiaki.common.DiscoveredDisplayHost
|
import com.metallic.chiaki.common.DiscoveredDisplayHost
|
||||||
import com.metallic.chiaki.common.DisplayHost
|
import com.metallic.chiaki.common.DisplayHost
|
||||||
import com.metallic.chiaki.common.Preferences
|
import com.metallic.chiaki.common.Preferences
|
||||||
|
@ -38,7 +36,7 @@ import com.metallic.chiaki.common.ext.viewModelFactory
|
||||||
import com.metallic.chiaki.common.getDatabase
|
import com.metallic.chiaki.common.getDatabase
|
||||||
import com.metallic.chiaki.lib.ConnectInfo
|
import com.metallic.chiaki.lib.ConnectInfo
|
||||||
import com.metallic.chiaki.lib.DiscoveryHost
|
import com.metallic.chiaki.lib.DiscoveryHost
|
||||||
import com.metallic.chiaki.lib.RegistEventSuccess
|
import com.metallic.chiaki.manualconsole.AddManualConsoleActivity
|
||||||
import com.metallic.chiaki.regist.RegistActivity
|
import com.metallic.chiaki.regist.RegistActivity
|
||||||
import com.metallic.chiaki.settings.SettingsActivity
|
import com.metallic.chiaki.settings.SettingsActivity
|
||||||
import com.metallic.chiaki.stream.StreamActivity
|
import com.metallic.chiaki.stream.StreamActivity
|
||||||
|
@ -153,7 +151,7 @@ class MainActivity : AppCompatActivity()
|
||||||
|
|
||||||
private fun addManualConsole()
|
private fun addManualConsole()
|
||||||
{
|
{
|
||||||
Intent(this, TestStartActivity::class.java).also {
|
Intent(this, AddManualConsoleActivity::class.java).also {
|
||||||
it.putRevealExtra(addManualButton, rootLayout)
|
it.putRevealExtra(addManualButton, rootLayout)
|
||||||
startActivity(it, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
|
startActivity(it, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Chiaki.
|
||||||
|
*
|
||||||
|
* Chiaki is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Chiaki is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.metallic.chiaki.manualconsole
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.view.Window
|
||||||
|
import android.widget.AdapterView
|
||||||
|
import android.widget.AdapterView.OnItemSelectedListener
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.ViewModelProviders
|
||||||
|
import com.metallic.chiaki.R
|
||||||
|
import com.metallic.chiaki.common.ManualHost
|
||||||
|
import com.metallic.chiaki.common.RegisteredHost
|
||||||
|
import com.metallic.chiaki.common.ext.RevealActivity
|
||||||
|
import com.metallic.chiaki.common.ext.viewModelFactory
|
||||||
|
import com.metallic.chiaki.common.getDatabase
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.addTo
|
||||||
|
import kotlinx.android.synthetic.main.activity_add_manual.*
|
||||||
|
|
||||||
|
class AddManualConsoleActivity: AppCompatActivity(), RevealActivity
|
||||||
|
{
|
||||||
|
override val revealIntent: Intent get() = intent
|
||||||
|
override val revealRootLayout: View get() = rootLayout
|
||||||
|
override val revealWindow: Window get() = window
|
||||||
|
|
||||||
|
private lateinit var viewModel: AddManualConsoleViewModel
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_add_manual)
|
||||||
|
handleReveal()
|
||||||
|
|
||||||
|
viewModel = ViewModelProviders
|
||||||
|
.of(this, viewModelFactory { AddManualConsoleViewModel(getDatabase(this)) })
|
||||||
|
.get(AddManualConsoleViewModel::class.java)
|
||||||
|
|
||||||
|
viewModel.selectedRegisteredHost.observe(this, Observer {
|
||||||
|
registeredHostTextView.setText(titleForRegisteredHost(it))
|
||||||
|
})
|
||||||
|
|
||||||
|
viewModel.registeredHosts.observe(this, Observer { hosts ->
|
||||||
|
registeredHostTextView.setAdapter(ArrayAdapter<String>(this, R.layout.dropdown_menu_popup_item,
|
||||||
|
hosts.map { titleForRegisteredHost(it) }))
|
||||||
|
registeredHostTextView.onItemClickListener = object: AdapterView.OnItemClickListener {
|
||||||
|
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long)
|
||||||
|
{
|
||||||
|
if(position >= hosts.size)
|
||||||
|
return
|
||||||
|
val host = hosts[position]
|
||||||
|
viewModel.selectedRegisteredHost.value = host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
saveButton.setOnClickListener { saveHost() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun titleForRegisteredHost(registeredHost: RegisteredHost?) =
|
||||||
|
if(registeredHost == null)
|
||||||
|
getString(R.string.add_manual_regist_on_connect)
|
||||||
|
else
|
||||||
|
"${registeredHost.ps4Nickname ?: ""} (${registeredHost.ps4Mac})"
|
||||||
|
|
||||||
|
private fun saveHost()
|
||||||
|
{
|
||||||
|
val host = hostEditText.text.toString().trim()
|
||||||
|
if(host.isEmpty())
|
||||||
|
{
|
||||||
|
hostEditText.error = getString(R.string.entered_host_invalid)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
saveButton.isEnabled = false
|
||||||
|
viewModel.saveHost(host)
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
.addTo(disposable)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Chiaki.
|
||||||
|
*
|
||||||
|
* Chiaki is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Chiaki is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.metallic.chiaki.manualconsole
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.metallic.chiaki.common.AppDatabase
|
||||||
|
import com.metallic.chiaki.common.ManualHost
|
||||||
|
import com.metallic.chiaki.common.RegisteredHost
|
||||||
|
import com.metallic.chiaki.common.ext.toLiveData
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
|
||||||
|
class AddManualConsoleViewModel(val database: AppDatabase): ViewModel()
|
||||||
|
{
|
||||||
|
val registeredHosts by lazy {
|
||||||
|
database.registeredHostDao().getAll().observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.doOnNext { hosts ->
|
||||||
|
val selectedHost = selectedRegisteredHost.value
|
||||||
|
if(selectedHost != null)
|
||||||
|
selectedRegisteredHost.value = hosts.firstOrNull { it.id == selectedHost.id }
|
||||||
|
}
|
||||||
|
.map { listOf(null) + it }
|
||||||
|
.toLiveData()
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedRegisteredHost = MutableLiveData<RegisteredHost?>(null)
|
||||||
|
|
||||||
|
fun saveHost(host: String) =
|
||||||
|
database.manualHostDao()
|
||||||
|
.insert(ManualHost(host = host, registeredHost = selectedRegisteredHost.value?.id))
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
}
|
|
@ -20,7 +20,6 @@ package com.metallic.chiaki.regist
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import android.util.Log
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
@ -112,7 +111,7 @@ class RegistActivity: AppCompatActivity(), RevealActivity
|
||||||
val pin = pinEditText.text.toString()
|
val pin = pinEditText.text.toString()
|
||||||
val pinValid = pin.length == PIN_LENGTH
|
val pinValid = pin.length == PIN_LENGTH
|
||||||
|
|
||||||
hostEditText.error = if(!hostValid) getString(R.string.regist_host_invalid) else null
|
hostEditText.error = if(!hostValid) getString(R.string.entered_host_invalid) else null
|
||||||
psnIdEditText.error =
|
psnIdEditText.error =
|
||||||
if(!psnIdValid)
|
if(!psnIdValid)
|
||||||
getString(when(ps4Version)
|
getString(when(ps4Version)
|
||||||
|
|
|
@ -55,9 +55,6 @@ class RegistExecuteActivity: AppCompatActivity()
|
||||||
.of(this, viewModelFactory { RegistExecuteViewModel(getDatabase(this)) })
|
.of(this, viewModelFactory { RegistExecuteViewModel(getDatabase(this)) })
|
||||||
.get(RegistExecuteViewModel::class.java)
|
.get(RegistExecuteViewModel::class.java)
|
||||||
|
|
||||||
showDuplicateDialog()
|
|
||||||
return
|
|
||||||
|
|
||||||
logTextView.setHorizontallyScrolling(true)
|
logTextView.setHorizontallyScrolling(true)
|
||||||
logTextView.movementMethod = ScrollingMovementMethod()
|
logTextView.movementMethod = ScrollingMovementMethod()
|
||||||
viewModel.logText.observe(this, Observer {
|
viewModel.logText.observe(this, Observer {
|
||||||
|
|
|
@ -28,7 +28,6 @@ import com.metallic.chiaki.common.ext.toLiveData
|
||||||
import com.metallic.chiaki.lib.*
|
import com.metallic.chiaki.lib.*
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import io.reactivex.functions.Action
|
|
||||||
import io.reactivex.rxkotlin.addTo
|
import io.reactivex.rxkotlin.addTo
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
|
||||||
|
@ -113,7 +112,7 @@ class RegistExecuteViewModel(val database: AppDatabase): ViewModel()
|
||||||
.andThen(dao.insert(registeredHost))
|
.andThen(dao.insert(registeredHost))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe { _ ->
|
.subscribe { _ -> /* No, IntelliJ, this "_ ->" IS necessary. */
|
||||||
Log.i("RegistExecute", "Registered Host saved in db")
|
Log.i("RegistExecute", "Registered Host saved in db")
|
||||||
_state.value = State.SUCCESSFUL
|
_state.value = State.SUCCESSFUL
|
||||||
}
|
}
|
||||||
|
|
23
android/app/src/main/res/drawable/ic_add_manual.xml
Normal file
23
android/app/src/main/res/drawable/ic_add_manual.xml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="505dp"
|
||||||
|
android:height="128dp"
|
||||||
|
android:viewportWidth="133.61458"
|
||||||
|
android:viewportHeight="33.86667">
|
||||||
|
<path
|
||||||
|
android:pathData="M15.6,3.81 L9.139,14.681L96.139,14.681l0,-1.98c-0.001,-2.013 1.629,-3.646 3.64,-3.647l9.048,0L108.827,3.81ZM6.461,19.186 L-0,30.057L108.827,30.057L108.827,24.812l-9.048,0c-2.011,-0.001 -3.64,-1.634 -3.64,-3.647l0,-1.979z"
|
||||||
|
android:strokeAlpha="1"
|
||||||
|
android:strokeWidth="53.1311"
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:fillAlpha="1"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m112.469,0l0,12.7l-12.688,0l0,8.467l12.688,0l0,12.7l8.458,0l0,-12.7l12.688,0l0,-8.467l-12.688,0l0,-12.7z"
|
||||||
|
android:strokeAlpha="1"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="5.29167"
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:fillAlpha="1"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
83
android/app/src/main/res/layout/activity_add_manual.xml
Normal file
83
android/app/src/main/res/layout/activity_add_manual.xml
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/rootLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?android:attr/windowBackground"
|
||||||
|
android:scrollbars="none">
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:animateLayoutChanges="true">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iconImageView"
|
||||||
|
android:layout_width="256dp"
|
||||||
|
android:layout_height="64dp"
|
||||||
|
android:src="@drawable/ic_add_manual"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:tint="?attr/colorOnPrimary"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
android:layout_marginTop="16dp"/>
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/titleTextView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/title_add_manual"
|
||||||
|
android:textSize="32sp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/iconImageView"
|
||||||
|
android:textAppearance="?attr/textAppearanceHeadline1"/>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/hostTextInputLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/hint_regist_host"
|
||||||
|
app:startIconDrawable="@drawable/ic_host"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/titleTextView"
|
||||||
|
android:layout_marginTop="32dp">
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/hostEditText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textNoSuggestions|textVisiblePassword"
|
||||||
|
android:maxLines="1"/>
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/registeredHostTextInputLayout"
|
||||||
|
style="@style/MageTheme.TextInputStyle.ExposedDropdownMenu"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/hint_add_manual_regist_host"
|
||||||
|
app:startIconDrawable="@drawable/ic_register"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/hostTextInputLayout"
|
||||||
|
android:layout_marginTop="32dp">
|
||||||
|
<AutoCompleteTextView
|
||||||
|
android:id="@+id/registeredHostTextView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:editable="false"
|
||||||
|
android:maxLines="1" /> <!-- editable is deprecated, but there is no alternative -->
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/saveButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/registeredHostTextInputLayout"
|
||||||
|
style="@style/MageTheme.Button"
|
||||||
|
android:text="@string/action_add_manual_save"
|
||||||
|
android:layout_marginTop="32dp" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</ScrollView>
|
|
@ -1,56 +0,0 @@
|
||||||
<?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:id="@+id/rootLayout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="?android:attr/windowBackground"
|
|
||||||
tools:context=".main.MainActivity">
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/hostEditText"
|
|
||||||
android:layout_width="200dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:hint="Host"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/registKeyEditText"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintVertical_chainStyle="packed"/>
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/registKeyEditText"
|
|
||||||
android:layout_width="200dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:hint="Regist Key"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/morningEditText"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/hostEditText" />
|
|
||||||
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/morningEditText"
|
|
||||||
android:layout_width="200dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:hint="Morning (base64)"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/startButton"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/registKeyEditText" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatButton
|
|
||||||
android:id="@+id/startButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Start"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/morningEditText" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textAppearance="?attr/textAppearanceSubtitle1"/>
|
|
@ -35,7 +35,7 @@
|
||||||
<string name="hint_regist_psn_account_id">PSN Account ID (8 bytes, base64)</string>
|
<string name="hint_regist_psn_account_id">PSN Account ID (8 bytes, base64)</string>
|
||||||
<string name="hint_regist_pin">PIN</string>
|
<string name="hint_regist_pin">PIN</string>
|
||||||
<string name="action_regist">Register</string>
|
<string name="action_regist">Register</string>
|
||||||
<string name="regist_host_invalid">Please enter a valid host name</string>
|
<string name="entered_host_invalid">Please enter a valid host name</string>
|
||||||
<string name="regist_psn_online_id_invalid">Please enter a valid PSN ID</string>
|
<string name="regist_psn_online_id_invalid">Please enter a valid PSN ID</string>
|
||||||
<string name="regist_psn_account_id_invalid">Please enter a valid 8-byte Account ID in Base64</string>
|
<string name="regist_psn_account_id_invalid">Please enter a valid 8-byte Account ID in Base64</string>
|
||||||
<string name="regist_pin_invalid">Please enter a valid %d-digit PIN</string>
|
<string name="regist_pin_invalid">Please enter a valid %d-digit PIN</string>
|
||||||
|
@ -45,6 +45,10 @@
|
||||||
<string name="alert_regist_duplicate">The console with MAC %s has already been registered. Should the previous record be overwritten?</string>
|
<string name="alert_regist_duplicate">The console with MAC %s has already been registered. Should the previous record be overwritten?</string>
|
||||||
<string name="action_regist_overwrite">Overwrite</string>
|
<string name="action_regist_overwrite">Overwrite</string>
|
||||||
<string name="action_regist_discard">Cancel</string>
|
<string name="action_regist_discard">Cancel</string>
|
||||||
|
<string name="title_add_manual">Add Console Manually</string>
|
||||||
|
<string name="action_add_manual_save">Save</string>
|
||||||
|
<string name="hint_add_manual_regist_host">Registered Console</string>
|
||||||
|
<string name="add_manual_regist_on_connect">Register on first Connection</string>
|
||||||
<string name="preferences_category_title_general">General</string>
|
<string name="preferences_category_title_general">General</string>
|
||||||
<string name="preferences_category_title_stream">Stream</string>
|
<string name="preferences_category_title_stream">Stream</string>
|
||||||
<string name="preferences_registered_hosts_title">Registered Consoles</string>
|
<string name="preferences_registered_hosts_title">Registered Consoles</string>
|
||||||
|
|
|
@ -77,6 +77,14 @@
|
||||||
<item name="boxBackgroundColor">?attr/colorPrimaryDark</item>
|
<item name="boxBackgroundColor">?attr/colorPrimaryDark</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="MageTheme.TextInputStyle.ExposedDropdownMenu" parent="Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu">
|
||||||
|
<item name="hintTextColor">?attr/colorAccent</item>
|
||||||
|
<item name="boxCornerRadiusTopStart">16dp</item>
|
||||||
|
<item name="boxCornerRadiusTopEnd">16dp</item>
|
||||||
|
<item name="boxStrokeColor">@color/mage_text_input_box_stroke</item>
|
||||||
|
<item name="boxBackgroundColor">?attr/colorPrimaryDark</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<style name="MageTheme.Button" parent="Widget.MaterialComponents.Button">
|
<style name="MageTheme.Button" parent="Widget.MaterialComponents.Button">
|
||||||
<item name="tint">?attr/colorOnSecondary</item>
|
<item name="tint">?attr/colorOnSecondary</item>
|
||||||
<item name="android:backgroundTint">?attr/colorSecondary</item>
|
<item name="android:backgroundTint">?attr/colorSecondary</item>
|
||||||
|
|
81
assets/add_console.svg
Normal file
81
assets/add_console.svg
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
sodipodi:docname="add_console.svg"
|
||||||
|
inkscape:version="1.0beta1 (5c3063637d, 2019-10-15)"
|
||||||
|
id="svg965"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 133.61458 33.866667"
|
||||||
|
height="128"
|
||||||
|
width="505">
|
||||||
|
<defs
|
||||||
|
id="defs959" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:lockguides="true"
|
||||||
|
inkscape:object-paths="true"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="15"
|
||||||
|
inkscape:window-x="1920"
|
||||||
|
inkscape:window-height="1048"
|
||||||
|
inkscape:window-width="1918"
|
||||||
|
units="px"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:cy="95.042315"
|
||||||
|
inkscape:cx="242.99039"
|
||||||
|
inkscape:zoom="1.979899"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata962">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
transform="translate(0,-263.13332)"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Ebene 1">
|
||||||
|
<g
|
||||||
|
transform="matrix(1.3766446,0,0,1.3780225,-1.5050122e-6,-108.03923)"
|
||||||
|
id="g936">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccccccccccccccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,0,264.7064)"
|
||||||
|
d="M 42.828125,28.005859 25.089844,57.822266 H 263.94727 v -5.429688 c -0.002,-5.521857 4.47228,-10.000119 9.99414,-10.003906 h 24.83984 V 28.005859 Z M 17.738281,70.179688 0,99.994141 H 298.78125 V 85.609375 h -24.83984 c -5.52109,-0.0038 -9.99467,-4.480859 -9.99414,-10.001953 v -5.427734 z"
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:53.1311;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path950" />
|
||||||
|
<g
|
||||||
|
style="opacity:1"
|
||||||
|
id="g859">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path863"
|
||||||
|
d="m 81.697855,269.35159 v 9.21598 h -9.216493 v 6.14433 h 9.216493 v 9.21597 h 6.143811 v -9.21597 h 9.21649 v -6.14433 h -9.21649 v -9.21598 z"
|
||||||
|
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.29167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.1 KiB |
Loading…
Add table
Add a link
Reference in a new issue