Change singleapp to fragment, put toolbar in activity, add search bar

This commit is contained in:
2020-11-02 19:24:26 +02:00
parent 54b1085d51
commit 95c6dbe556
26 changed files with 474 additions and 307 deletions
+5 -4
View File
@@ -57,18 +57,19 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2' implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0" implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation 'com.github.doyaaaaaken:kotlin-csv-jvm:0.11.1' implementation 'com.github.doyaaaaaken:kotlin-csv-jvm:0.11.1'
implementation 'com.github.wrdlbrnft:sorted-list-adapter:0.3.0.27'
implementation "androidx.cardview:cardview:1.0.0" implementation "androidx.cardview:cardview:1.0.0"
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0' implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0' implementation 'androidx.navigation:navigation-ui-ktx:2.3.1'
implementation 'androidx.preference:preference-ktx:1.1.1' implementation 'androidx.preference:preference-ktx:1.1.1'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.1.0'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.google.android.material:material:1.2.1' implementation 'com.google.android.material:material:1.2.1'
+1 -7
View File
@@ -18,18 +18,12 @@
<activity android:name=".activities.SplashActivity" android:theme="@style/NPSTheme.Splash"> <activity android:name=".activities.SplashActivity" android:theme="@style/NPSTheme.Splash">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".activities.MainActivity" <activity android:name=".activities.MainActivity"
android:configChanges="screenSize|screenLayout|keyboardHidden"> android:configChanges="screenSize|screenLayout|keyboardHidden|orientation">
</activity> </activity>
<activity
android:name=".activities.SingleAppActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"
android:parentActivityName=".activities.MainActivity" />
</application> </application>
</manifest> </manifest>
@@ -1,5 +1,59 @@
package com.illusionware.npsbrowser package com.illusionware.npsbrowser
data class AppData(val titleID: String?, val region: String?, val title : String?, val link : String?, import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter
val license : String?, val contentID : String?, val lastDateTime: String?,
val fileSize : Number?, val sha256 : String?, val minFW : String?) data class AppData(
val titleID: String?, val region: String?, val title: String?, val link: String?,
val license: String?, val contentID: String?, val lastDateTime: String?,
val fileSize: Number?, val sha256: String?, val minFW: String?
) : SortedListAdapter.ViewModel {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as AppData
if (titleID != other.titleID) return false
if (region != other.region) return false
if (title != other.title) return false
if (link != other.link) return false
if (license != other.license) return false
if (contentID != other.contentID) return false
if (lastDateTime != other.lastDateTime) return false
if (fileSize != other.fileSize) return false
if (sha256 != other.sha256) return false
if (minFW != other.minFW) return false
return true
}
override fun hashCode(): Int {
var result = titleID?.hashCode() ?: 0
result = 31 * result + (region?.hashCode() ?: 0)
result = 31 * result + (title?.hashCode() ?: 0)
result = 31 * result + (link?.hashCode() ?: 0)
result = 31 * result + (license?.hashCode() ?: 0)
result = 31 * result + (contentID?.hashCode() ?: 0)
result = 31 * result + (lastDateTime?.hashCode() ?: 0)
result = 31 * result + (fileSize?.hashCode() ?: 0)
result = 31 * result + (sha256?.hashCode() ?: 0)
result = 31 * result + (minFW?.hashCode() ?: 0)
return result
}
override fun <T : Any?> isSameModelAs(model: T): Boolean {
if (model is AppData) {
val other: AppData = model as AppData
return "${other.titleID} ${other.title}" == "$titleID $title"
}
return false
}
override fun <T : Any?> isContentTheSameAs(model: T): Boolean {
if (model is AppData) {
val other: AppData = model as AppData
return title?.equals(other.title) ?: (other.title == null)
}
return false
}
}
@@ -2,18 +2,26 @@ package com.illusionware.npsbrowser.activities
import android.os.Bundle import android.os.Bundle
import android.view.MenuItem import android.view.MenuItem
import androidx.fragment.app.FragmentManager
import com.illusionware.npsbrowser.R import com.illusionware.npsbrowser.R
import com.illusionware.npsbrowser.fragments.mainactivity.MainActivityFragment import com.illusionware.npsbrowser.fragments.mainactivity.MainActivityFragment
class MainActivity : BaseActivity() { class MainActivity : BaseActivity(), FragmentManager.OnBackStackChangedListener {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setTheme(R.style.NPSTheme) setTheme(R.style.NPSTheme)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
supportFragmentManager.addOnBackStackChangedListener(this);
if (supportFragmentManager.backStackEntryCount > 0) {
showUpButton()
}
if (savedInstanceState == null) { if (savedInstanceState == null) {
supportFragmentManager.beginTransaction() supportFragmentManager.beginTransaction()
.replace(R.id.container, MainActivityFragment.newInstance()) .replace(R.id.container, MainActivityFragment())
.commitNow() .commitNow()
} }
} }
@@ -28,12 +36,20 @@ class MainActivity : BaseActivity() {
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
fun showUpButton() { override fun onBackStackChanged() {
// enable Up button only if there are entries on the backstack
if (supportFragmentManager.backStackEntryCount < 1) {
hideUpButton()
} else {
showUpButton()
}
}
private fun showUpButton() {
supportActionBar!!.setDisplayHomeAsUpEnabled(true) supportActionBar!!.setDisplayHomeAsUpEnabled(true)
} }
fun hideUpButton() { private fun hideUpButton() {
supportActionBar!!.setDisplayHomeAsUpEnabled(false) supportActionBar!!.setDisplayHomeAsUpEnabled(false)
} }
} }
@@ -1,104 +0,0 @@
package com.illusionware.npsbrowser.activities
import android.app.DownloadManager
import android.content.ClipData
import android.content.ClipboardManager
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.View
import android.widget.Toast
import com.illusionware.npsbrowser.AppData
import com.illusionware.npsbrowser.databinding.ActivitySingleAppBinding
import java.lang.Exception
class SingleAppActivity: BaseActivity() {
companion object {
lateinit var app : AppData
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivitySingleAppBinding.inflate(layoutInflater)
setContentView(binding.root)
var downloadManager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager
binding.singleAppTitle.text = "[${app.titleID}] ${app.title}"
if (app.fileSize != null) {
binding.singleAppSize.text = prettifySize()
} else {
binding.singleAppSizeTitle.visibility = View.INVISIBLE
}
binding.singleAppContentId.text = app.contentID
binding.singleAppFwVer.text = app.minFW
// TODO: get and set app icon
if (app.minFW.isNullOrBlank()) {
binding.singleAppFwVerTitle.visibility = View.INVISIBLE
}
if (app.license == "MISSING") {
binding.singleAppError.text = "Warning: No license was provided for this app."
}
if (app.link == "CART ONLY") {
binding.singleAppError.text = "CART ONLY GAME"
binding.singleAppDownloadButton.isEnabled = false
} else if (app.link == "MISSING") {
binding.singleAppError.text = "Warning: No download link was provided for this app."
binding.singleAppDownloadButton.isEnabled = false
}
binding.singleAppContentId.setOnLongClickListener {
val clipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("Content ID", binding.singleAppContentId.text)
clipboardManager.setPrimaryClip(clipData)
Toast.makeText(this, "Content ID Copied to Clipboard!", Toast.LENGTH_SHORT).show()
true
}
binding.singleAppDownloadButton.setOnClickListener {
try {
var request = DownloadManager.Request(Uri.parse(app.link))
request.setTitle(app.title)
request.setDescription("Downloading...")
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, app.title + ".pkg") // TODO: set up preference for this
downloadManager.enqueue(request)
} catch (e: Exception) {
Toast.makeText(this, "An error occurred while downloading. please try again", Toast.LENGTH_SHORT).show()
}
}
binding.singleAppDownloadButton.setOnLongClickListener {
val clipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("PKG URL", app.link)
clipboardManager.setPrimaryClip(clipData)
Toast.makeText(this, "PKG URL Copied to Clipboard", Toast.LENGTH_SHORT).show()
true
}
}
private fun prettifySize(): String {
if (app.fileSize!!.toFloat() / (1024 * 1024 * 1024) > 1) {
return "%.1f GB".format(toGB(app.fileSize!!))
}
if (app.fileSize!!.toFloat() / (1024 * 1024) > 1) {
return "%.1f MB".format(toMB(app.fileSize!!))
}
if (app.fileSize!!.toFloat() / 1024 > 1) {
return "%.1f KB".format(toKB(app.fileSize!!))
}
return "${app.fileSize!!} Bytes";
}
private fun toKB(size: Number): Number {
return size.toFloat() / 1024
}
private fun toMB(size: Number): Number {
return size.toFloat() / (1024 * 1024)
}
private fun toGB(size: Number): Number {
return size.toFloat() / (1024 * 1024 * 1024)
}
}
@@ -1,33 +1,73 @@
package com.illusionware.npsbrowser.adapters package com.illusionware.npsbrowser.adapters
import android.content.Context import android.content.Context
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView import com.github.wrdlbrnft.modularadapter.ModularAdapter
import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter
import com.illusionware.npsbrowser.AppData import com.illusionware.npsbrowser.AppData
import com.illusionware.npsbrowser.R import com.illusionware.npsbrowser.R
import kotlin.collections.ArrayList import com.illusionware.npsbrowser.activities.MainActivity
import com.illusionware.npsbrowser.fragments.SingleAppFragment
import com.illusionware.npsbrowser.fragments.mainactivity.MainActivityFragment
import java.util.Comparator
class AppAdapter(private val appsList: ArrayList<AppData>, val context : Context) : RecyclerView.Adapter<AppAdapter.ViewHolder>() { private val comparator: Comparator<AppData> = SortedListAdapter.ComparatorBuilder<AppData>()
private final val LIST_ITEM = 0 .setOrderForModel(AppData::class.java) { a, b -> a.title?.compareTo(b.title!!)!! }
private final val GRID_ITEM = 1 .build()
var isSwitchView = true
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { class AppAdapter(val context: Context) : SortedListAdapter<AppData>(context, AppData::class.java, comparator) {
var appTitle: TextView = view.findViewById(R.id.appTitle) private val LIST_ITEM = 0
var appRegion: TextView = view.findViewById(R.id.appRegion) private val GRID_ITEM = 1
var appMinFW: TextView = view.findViewById(R.id.appMinFW) private var isSwitchView = true
var appLastDate: TextView = view.findViewById(R.id.appLastDate)
inner class AppViewHolder(itemView: View) :
SortedListAdapter.ViewHolder<AppData?>(itemView) {
var appTitle: TextView = itemView.findViewById(R.id.appTitle)
var appRegion: TextView = itemView.findViewById(R.id.appRegion)
var appMinFW: TextView = itemView.findViewById(R.id.appMinFW)
var appLastDate: TextView = itemView.findViewById(R.id.appLastDate)
override fun performBind(item: AppData) {
appTitle.text = item.title
appTitle.isSelected = true
appRegion.text = item.region
appMinFW.text = item.minFW
appMinFW.background = null;
if (appMinFW.text.isNotBlank()) {
val drawable = ResourcesCompat.getDrawable(
context.resources,
R.drawable.rect_red,
null
)
appMinFW.background = drawable;
}
appLastDate.text = item.lastDateTime
}
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(inflater: LayoutInflater, parent: ViewGroup, viewType: Int): AppViewHolder {
return if (viewType == LIST_ITEM) { return if (viewType == LIST_ITEM) {
ViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)) AppViewHolder(
inflater.inflate(
R.layout.recycler_item_list,
parent,
false
)
)
} else { } else {
ViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.grid_item, parent, false)) AppViewHolder(
inflater.inflate(
R.layout.recycler_item_grid,
parent,
false
)
)
} }
} }
@@ -39,34 +79,8 @@ class AppAdapter(private val appsList: ArrayList<AppData>, val context : Context
} }
} }
public fun toggleItemViewType(type: Int): Boolean { fun toggleItemViewType(type: Int): Boolean {
isSwitchView = type == 0 isSwitchView = type == 0
return isSwitchView return isSwitchView
} }
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.appTitle.text = appsList[position].title
holder.appTitle.isSelected = true
holder.appRegion.text = appsList[position].region
holder.appMinFW.text = appsList[position].minFW
holder.appMinFW.background = null;
if (holder.appMinFW.text.isNotBlank()) {
val drawable = ResourcesCompat.getDrawable(context.resources, R.drawable.rect_red, null)
holder.appMinFW.background = drawable;
}
holder.appLastDate.text = appsList[position].lastDateTime
}
override fun getItemCount(): Int {
return appsList.size
}
fun updateData(apps: ArrayList<AppData>) {
appsList.clear()
notifyDataSetChanged()
appsList.addAll(apps)
notifyDataSetChanged()
}
} }
@@ -1,33 +1,23 @@
package com.illusionware.npsbrowser.fragments package com.illusionware.npsbrowser.fragments
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.*
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN import androidx.fragment.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.illusionware.npsbrowser.R import com.illusionware.npsbrowser.R
import com.illusionware.npsbrowser.activities.BaseActivity
import com.illusionware.npsbrowser.activities.MainActivity
import com.illusionware.npsbrowser.fragments.mainactivity.MainActivityFragment
import kotlinx.android.synthetic.main.appbar.*
class SettingsFragment : Fragment() { class SettingsFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
if (activity!!.supportFragmentManager.backStackEntryCount < 1) {
(activity as MainActivity?)?.showUpButton()
MainActivityFragment().recyclerView?.adapter = MainActivityFragment().viewAdapter
}
PreferenceManager.setDefaultValues(context, R.xml.root_preferences, false); PreferenceManager.setDefaultValues(context, R.xml.root_preferences, false);
activity?.supportFragmentManager activity?.supportFragmentManager
?.beginTransaction() ?.beginTransaction()
?.replace( ?.replace(
R.id.prefs, R.id.prefs,
SettingsFragment() PrefsFragment()
) )
?.setTransition(TRANSIT_FRAGMENT_OPEN) ?.setTransition(TRANSIT_FRAGMENT_OPEN)
?.commit() ?.commit()
@@ -42,24 +32,11 @@ class SettingsFragment : Fragment() {
return inflater.inflate(R.layout.settings_fragment, container, false) return inflater.inflate(R.layout.settings_fragment, container, false)
} }
override fun onActivityCreated(savedInstanceState: Bundle?) { class PrefsFragment : PreferenceFragmentCompat() {
super.onActivityCreated(savedInstanceState)
(activity as BaseActivity?)!!.setSupportActionBar(toolbar)
(activity as BaseActivity?)!!.supportActionBar?.setDisplayHomeAsUpEnabled(true)
//viewModel = ViewModelProviders.of(this).get(MainActivity2ViewModel::class.java)
// TODO: Use the ViewModel
}
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey) setPreferencesFromResource(R.xml.root_preferences, rootKey)
PreferenceManager.setDefaultValues(context, R.xml.root_preferences, false); PreferenceManager.setDefaultValues(context, R.xml.root_preferences, false);
} }
override fun onActivityCreated(savedInstanceState: Bundle?) {
//(activity as BaseActivity?)!!.setSupportActionBar(toolbar)
super.onActivityCreated(savedInstanceState)
}
} }
} }
@@ -0,0 +1,115 @@
package com.illusionware.npsbrowser.fragments
import android.app.DownloadManager
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context.CLIPBOARD_SERVICE
import android.content.Context.DOWNLOAD_SERVICE
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.illusionware.npsbrowser.AppData
import com.illusionware.npsbrowser.R
import java.lang.Exception
class SingleAppFragment : Fragment() {
companion object {
lateinit var app : AppData
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreateView(inflater, container, savedInstanceState)
activity?.title = app.title
val view = inflater.inflate(R.layout.single_app_fragment, container, false)
val downloadManager = requireActivity().getSystemService(DOWNLOAD_SERVICE) as DownloadManager
view?.findViewById<TextView>(R.id.singleAppTitle)?.text = "[${app.titleID}] ${app.title}"
if (app.fileSize != null) {
view?.findViewById<TextView>(R.id.singleAppSize)?.text = prettifySize()
} else {
view?.findViewById<TextView>(R.id.singleAppSizeTitle)?.visibility = View.INVISIBLE
}
view?.findViewById<TextView>(R.id.singleAppContentId)?.text = app.contentID
view?.findViewById<TextView>(R.id.singleAppFwVer)?.text = app.minFW
// TODO: get and set app icon
if (app.minFW.isNullOrBlank()) {
view?.findViewById<TextView>(R.id.singleAppFwVerTitle)?.visibility = View.INVISIBLE
}
if (app.license == "MISSING") {
view?.findViewById<TextView>(R.id.singleAppError)?.text = "Warning: No license was provided for this app."
}
if (app.link == "CART ONLY") {
view?.findViewById<TextView>(R.id.singleAppError)?.text = "CART ONLY GAME"
view?.findViewById<Button>(R.id.singleAppDownloadButton)?.isEnabled = false
} else if (app.link == "MISSING") {
view?.findViewById<TextView>(R.id.singleAppError)?.text = "Warning: No download link was provided for this app."
view?.findViewById<Button>(R.id.singleAppDownloadButton)?.isEnabled = false
}
view?.findViewById<TextView>(R.id.singleAppContentId)?.setOnLongClickListener {
val clipboardManager = requireActivity().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("Content ID", view?.findViewById<TextView>(R.id.singleAppContentId)?.text)
clipboardManager.setPrimaryClip(clipData)
Toast.makeText(requireContext(), "Content ID Copied to Clipboard!", Toast.LENGTH_SHORT).show()
true
}
view?.findViewById<Button>(R.id.singleAppDownloadButton)?.setOnClickListener {
try {
var request = DownloadManager.Request(Uri.parse(app.link))
request.setTitle(app.title)
request.setDescription("Downloading...")
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, app.title + ".pkg") // TODO: set up preference for this
downloadManager.enqueue(request)
} catch (e: Exception) {
Toast.makeText(requireContext(), "An error occurred while downloading. please try again", Toast.LENGTH_SHORT).show()
}
}
view?.findViewById<Button>(R.id.singleAppDownloadButton)?.setOnLongClickListener {
val clipboardManager = requireActivity().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("PKG URL", app.link)
clipboardManager.setPrimaryClip(clipData)
Toast.makeText(requireContext(), "PKG URL Copied to Clipboard", Toast.LENGTH_SHORT).show()
true
}
return view
}
private fun prettifySize(): String {
if (app.fileSize!!.toFloat() / (1024 * 1024 * 1024) > 1) {
return "%.1f GB".format(toGB(app.fileSize!!))
}
if (app.fileSize!!.toFloat() / (1024 * 1024) > 1) {
return "%.1f MB".format(toMB(app.fileSize!!))
}
if (app.fileSize!!.toFloat() / 1024 > 1) {
return "%.1f KB".format(toKB(app.fileSize!!))
}
return "${app.fileSize!!} Bytes";
}
private fun toKB(size: Number): Number {
return size.toFloat() / 1024
}
private fun toMB(size: Number): Number {
return size.toFloat() / (1024 * 1024)
}
private fun toGB(size: Number): Number {
return size.toFloat() / (1024 * 1024 * 1024)
}
}
@@ -6,12 +6,11 @@ import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.* import android.view.*
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.widget.SearchView
import androidx.core.content.ContextCompat.checkSelfPermission import androidx.core.content.ContextCompat.checkSelfPermission
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
@@ -22,21 +21,18 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.illusionware.npsbrowser.AppData import com.illusionware.npsbrowser.AppData
import com.illusionware.npsbrowser.R import com.illusionware.npsbrowser.R
import com.illusionware.npsbrowser.RecyclerTouchListener import com.illusionware.npsbrowser.RecyclerTouchListener
import com.illusionware.npsbrowser.activities.SingleAppActivity import com.illusionware.npsbrowser.fragments.SingleAppFragment
import com.illusionware.npsbrowser.activities.MainActivity
import com.illusionware.npsbrowser.adapters.AppAdapter import com.illusionware.npsbrowser.adapters.AppAdapter
import com.illusionware.npsbrowser.fragments.SettingsFragment import com.illusionware.npsbrowser.fragments.SettingsFragment
import kotlinx.android.synthetic.main.appbar.*
import java.io.InputStream import java.io.InputStream
class MainActivityFragment : Fragment(), FragmentManager.OnBackStackChangedListener { class MainActivityFragment : Fragment() {
var recyclerView : RecyclerView? = null var recyclerView : RecyclerView? = null
var viewAdapter: AppAdapter? = null var viewAdapter: AppAdapter? = null
var filteredModelList: ArrayList<AppData>? = null
companion object { companion object {
fun newInstance() = MainActivityFragment()
var apps : ArrayList<AppData>? = arrayListOf() var apps : ArrayList<AppData>? = arrayListOf()
} }
@@ -51,69 +47,15 @@ class MainActivityFragment : Fragment(), FragmentManager.OnBackStackChangedListe
private lateinit var viewModel: MainActivityViewModel private lateinit var viewModel: MainActivityViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activity?.supportFragmentManager?.addOnBackStackChangedListener(this);
setHasOptionsMenu(true)
}
override fun onBackStackChanged() {
// enable Up button only if there are entries on the backstack
if (requireActivity().supportFragmentManager.backStackEntryCount < 1) {
(activity as MainActivity?)?.hideUpButton()
}
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
setHasOptionsMenu(true)
activity?.title = resources.getString(R.string.app_name) activity?.title = resources.getString(R.string.app_name)
val view = inflater.inflate(R.layout.main_fragment, container, false) val view = inflater.inflate(R.layout.main_fragment, container, false)
recyclerView = view?.findViewById(R.id.appsRecycler)
if (apps != null) {
viewAdapter = AppAdapter(apps!!, requireContext())
}
viewAdapter?.notifyDataSetChanged()
val orientation = this.resources.configuration.orientation
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val isViewAsList = prefs.getString("layout_type", "0")
if (isViewAsList == "0") {
viewAdapter?.toggleItemViewType(0)
recyclerView?.layoutManager = LinearLayoutManager(context)
viewAdapter?.notifyDataSetChanged()
} else {
viewAdapter?.toggleItemViewType(1)
recyclerView?.layoutManager = GridLayoutManager(context,
if (orientation == Configuration.ORIENTATION_LANDSCAPE) 4 else 2)
viewAdapter?.notifyDataSetChanged()
}
recyclerView?.adapter = viewAdapter
recyclerView?.addOnItemTouchListener(RecyclerTouchListener(requireContext(), recyclerView!!, object : RecyclerTouchListener.ClickListener {
override fun onClick(view: View?, position: Int) {
val myIntent = Intent(context, SingleAppActivity::class.java)
SingleAppActivity.app = apps!![position]
startActivity(myIntent)
}
override fun onLongClick(view: View?, recyclerView: RecyclerView?, position: Int) {
Toast.makeText(context, "TODO: Long Click ", Toast.LENGTH_SHORT).show()
}
}
))
return view
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(activity as MainActivity?)!!.setSupportActionBar(toolbar)
view?.findViewById<FloatingActionButton>(R.id.tsvChooserButton)?.setOnClickListener { view?.findViewById<FloatingActionButton>(R.id.tsvChooserButton)?.setOnClickListener {
if (!isStoragePermissionGranted()) if (!isStoragePermissionGranted())
return@setOnClickListener return@setOnClickListener
@@ -125,35 +67,68 @@ class MainActivityFragment : Fragment(), FragmentManager.OnBackStackChangedListe
} }
viewModel = ViewModelProviders.of(this).get(MainActivityViewModel::class.java) viewModel = ViewModelProviders.of(this).get(MainActivityViewModel::class.java)
// TODO: Use the ViewModel // TODO: Use the ViewModel
}
override fun onCreateOptionsMenu(menu : Menu, menuInflater : MenuInflater) { recyclerView = view?.findViewById(R.id.appsRecycler)
menuInflater.inflate(R.menu.toolbar_main, menu)
super.onCreateOptionsMenu(menu, menuInflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean { if (viewAdapter == null) {
return when (item.itemId) { viewAdapter = AppAdapter(requireContext())
R.id.action_settings -> { viewAdapter?.edit()?.add(apps!!)?.commit()
activity?.supportFragmentManager
?.beginTransaction()
?.replace(
R.id.container,
SettingsFragment()
)
?.addToBackStack("settings")
?.commit()
true
}
else -> return super.onOptionsItemSelected(item)
} }
if (apps != null) {
filteredModelList = apps
}
viewAdapter?.notifyDataSetChanged()
recyclerView?.adapter = viewAdapter
val orientation = resources.configuration.orientation
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val isViewAsList = prefs.getString("layout_type", "0")
if (isViewAsList == "0") {
viewAdapter?.toggleItemViewType(0)
recyclerView?.layoutManager = LinearLayoutManager(context)
viewAdapter?.notifyDataSetChanged()
} else {
viewAdapter?.toggleItemViewType(1)
recyclerView?.layoutManager = GridLayoutManager(
context,
if (orientation == Configuration.ORIENTATION_LANDSCAPE) 4 else 2
)
viewAdapter?.notifyDataSetChanged()
}
recyclerView?.addOnItemTouchListener(RecyclerTouchListener(
requireContext(),
recyclerView!!,
object : RecyclerTouchListener.ClickListener {
override fun onClick(view: View?, position: Int) {
SingleAppFragment.app = filteredModelList!![position]
activity?.supportFragmentManager
?.beginTransaction()
?.replace(R.id.container,
SingleAppFragment()
)
?.addToBackStack("single app")
?.commit()
}
override fun onLongClick(
view: View?,
recyclerView: RecyclerView?,
position: Int
) {
Toast.makeText(context, "TODO: Long Click $position", Toast.LENGTH_SHORT).show()
}
}
))
return view
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData) super.onActivityResult(requestCode, resultCode, resultData)
if (requestCode == 1 && resultCode == Activity.RESULT_OK) { if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
resultData?.data?.also { uri -> resultData?.data?.also { uri ->
Log.d("file_location", uri.toString())
val inputStream: InputStream? = activity?.contentResolver?.openInputStream(uri) val inputStream: InputStream? = activity?.contentResolver?.openInputStream(uri)
val entries : List<Map<String, String?>> = tsvReader.readAllWithHeader(inputStream!!) val entries : List<Map<String, String?>> = tsvReader.readAllWithHeader(inputStream!!)
apps?.clear() apps?.clear()
@@ -176,15 +151,19 @@ class MainActivityFragment : Fragment(), FragmentManager.OnBackStackChangedListe
val fileSize = entry["File Size"]?.toLongOrNull() val fileSize = entry["File Size"]?.toLongOrNull()
val sha256 = entry["SHA256"] val sha256 = entry["SHA256"]
val minFW = entry["Required FW"] val minFW = entry["Required FW"]
val app = AppData(id, region, name, link ?: "MISSING", license ?: "MISSING", val app = AppData(
id, region, name, link ?: "MISSING", license ?: "MISSING",
contentID ?: "MISSING", lastDateTime ?: "MISSING", contentID ?: "MISSING", lastDateTime ?: "MISSING",
fileSize, sha256 ?: "MISSING", minFW) fileSize, sha256 ?: "MISSING", minFW
)
apps?.add(app) apps?.add(app)
} }
apps?.sortBy { it.title } apps?.sortBy { it.title }
filteredModelList = apps
recyclerView = view?.findViewById(R.id.appsRecycler) recyclerView = view?.findViewById(R.id.appsRecycler)
viewAdapter = AppAdapter(apps!!, requireContext()) viewAdapter = AppAdapter(requireContext())
viewAdapter?.edit()?.add(apps!!)?.commit()
val orientation = this.resources.configuration.orientation val orientation = this.resources.configuration.orientation
val prefs = PreferenceManager.getDefaultSharedPreferences(context) val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val isViewAsList = prefs.getString("layout_type", "0") val isViewAsList = prefs.getString("layout_type", "0")
@@ -195,8 +174,10 @@ class MainActivityFragment : Fragment(), FragmentManager.OnBackStackChangedListe
viewAdapter?.notifyDataSetChanged() viewAdapter?.notifyDataSetChanged()
} else { } else {
viewAdapter?.toggleItemViewType(1) viewAdapter?.toggleItemViewType(1)
recyclerView?.layoutManager = GridLayoutManager(context, recyclerView?.layoutManager = GridLayoutManager(
if (orientation == Configuration.ORIENTATION_LANDSCAPE) 4 else 2) context,
if (orientation == Configuration.ORIENTATION_LANDSCAPE) 4 else 2
)
viewAdapter?.notifyDataSetChanged() viewAdapter?.notifyDataSetChanged()
} }
@@ -205,14 +186,96 @@ class MainActivityFragment : Fragment(), FragmentManager.OnBackStackChangedListe
} }
} }
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.main, menu)
val searchItem = menu.findItem(R.id.action_search)
val searchView: SearchView = searchItem.actionView as SearchView
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(query: String): Boolean {
filteredModelList = filter(apps!!, query) as ArrayList<AppData>?
viewAdapter?.edit()?.replaceAll(filteredModelList!!)?.commit()
recyclerView?.scrollToPosition(0)
return false
}
})
super.onCreateOptionsMenu(menu, menuInflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_settings -> {
activity?.supportFragmentManager
?.beginTransaction()
?.replace(
R.id.container,
SettingsFragment()
)
?.addToBackStack("settings")
?.commit()
true
}
R.id.action_search -> {
true
}
else -> return super.onOptionsItemSelected(item)
}
}
override fun onPause() {
super.onPause()
viewAdapter?.edit()?.replaceAll(apps!!)?.commit()
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
val orientation = newConfig.orientation
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val isViewAsList = prefs.getString("layout_type", "0")
if (isViewAsList == "0") {
val pos = (recyclerView?.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
viewAdapter?.toggleItemViewType(0)
recyclerView?.layoutManager = LinearLayoutManager(context)
(recyclerView?.layoutManager as LinearLayoutManager).scrollToPosition(pos)
viewAdapter?.notifyDataSetChanged()
} else {
val pos = (recyclerView?.layoutManager as GridLayoutManager).findFirstVisibleItemPosition()
viewAdapter?.toggleItemViewType(1)
recyclerView?.layoutManager = GridLayoutManager(
context,
if (orientation == Configuration.ORIENTATION_LANDSCAPE) 4 else 2
)
(recyclerView?.layoutManager as GridLayoutManager).scrollToPosition(pos)
viewAdapter?.notifyDataSetChanged()
}
}
private fun isStoragePermissionGranted(): Boolean { private fun isStoragePermissionGranted(): Boolean {
return if (checkSelfPermission(this.context!!, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { return if (checkSelfPermission(
Log.v("perms", "Permission is granted") this.requireContext(),
Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED) {
true true
} else { } else {
Log.v("perms", "Permission is revoked")
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1) requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1)
false false
} }
} }
private fun filter(models: List<AppData>, query: String): List<AppData>? {
val lowerCaseQuery = query.toLowerCase()
val filteredModelList: MutableList<AppData> = ArrayList()
for (model in models) {
val title: String = model.title?.toLowerCase()!!
val id: String = model.titleID?.toLowerCase()!!
if (title.contains(lowerCaseQuery) || id.contains(lowerCaseQuery)) {
filteredModelList.add(model)
}
}
return filteredModelList
}
} }
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>
+27 -3
View File
@@ -1,7 +1,31 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <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" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container" android:id="@+id/main"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".activities.MainActivity" /> android:clipChildren="false">
<include
android:id="@+id/include"
layout="@layout/appbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:background="@color/colorAmoled"
android:backgroundTint="@color/colorAmoled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/include"
tools:context=".activities.MainActivity" />
</androidx.constraintlayout.widget.ConstraintLayout>
+1
View File
@@ -12,6 +12,7 @@
style="@style/Widget.MaterialComponents.Toolbar.Primary" style="@style/Widget.MaterialComponents.Toolbar.Primary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="@color/colorAmoled"
android:theme="@style/NPSTheme.ActionBar" android:theme="@style/NPSTheme.ActionBar"
app:layout_scrollFlags="scroll|enterAlways|snap" /> app:layout_scrollFlags="scroll|enterAlways|snap" />
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
+5 -4
View File
@@ -7,8 +7,6 @@
android:clipChildren="false" android:clipChildren="false"
tools:context=".fragments.mainactivity.MainActivityFragment"> tools:context=".fragments.mainactivity.MainActivityFragment">
<include layout="@layout/appbar" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/appsRecycler" android:id="@+id/appsRecycler"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -21,18 +19,21 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2" app:spanCount="2"
tools:listitem="@layout/grid_item" /> tools:listitem="@layout/recycler_item_grid" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/tsvChooserButton" android:id="@+id/tsvChooserButton"
android:layout_width="52dp" android:layout_width="52dp"
android:layout_height="52dp" android:layout_height="52dp"
android:layout_marginBottom="40dp" android:layout_marginBottom="40dp"
android:backgroundTint="@color/colorPrimary"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:src="@drawable/ic_add_yellow_24dp" android:src="@drawable/ic_add_24dp"
app:borderWidth="2dp"
app:fabCustomSize="52dp" app:fabCustomSize="52dp"
app:layout_anchor="@+id/appsRecycler" app:layout_anchor="@+id/appsRecycler"
app:layout_anchorGravity="bottom|center" app:layout_anchorGravity="bottom|center"
app:maxImageSize="32dp" /> app:maxImageSize="32dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -15,6 +15,7 @@
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="214dp" android:layout_height="214dp"
android:backgroundTint="@color/colorAmoled"
app:cardBackgroundColor="@color/colorPrimary" app:cardBackgroundColor="@color/colorPrimary"
app:cardElevation="4dp" app:cardElevation="4dp"
app:cardUseCompatPadding="false" app:cardUseCompatPadding="false"
@@ -34,7 +35,7 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_games_black_24dp" /> app:srcCompat="@drawable/ic_games_placeholder_24dp" />
<TextView <TextView
android:id="@+id/appTitle" android:id="@+id/appTitle"
@@ -15,6 +15,7 @@
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:backgroundTint="@color/colorAmoled"
app:cardBackgroundColor="@color/colorPrimary" app:cardBackgroundColor="@color/colorPrimary"
app:cardElevation="4dp" app:cardElevation="4dp"
app:cardUseCompatPadding="false" app:cardUseCompatPadding="false"
@@ -32,7 +33,7 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_games_black_24dp" /> app:srcCompat="@drawable/ic_games_placeholder_24dp" />
<TextView <TextView
android:id="@+id/appTitle" android:id="@+id/appTitle"
+1 -11
View File
@@ -7,24 +7,14 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipChildren="false"> android:clipChildren="false">
<include
android:id="@+id/include"
layout="@layout/appbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout <FrameLayout
android:id="@+id/prefs" android:id="@+id/prefs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="56dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/include"> app:layout_constraintTop_toTopOf="parent">
</FrameLayout> </FrameLayout>
@@ -173,7 +173,7 @@
android:layout_marginTop="30dp" android:layout_marginTop="30dp"
android:layout_marginEnd="141dp" android:layout_marginEnd="141dp"
android:contentDescription="Single app icon" android:contentDescription="Single app icon"
app:srcCompat="@drawable/ic_games_black_24dp" /> app:srcCompat="@drawable/ic_games_placeholder_24dp" />
</LinearLayout> </LinearLayout>
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu 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">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search_24dp"
android:title="@string/search"
app:iconTint="?attr/colorOnPrimary"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="always" />
<item <item
android:id="@+id/action_settings" android:id="@+id/action_settings"
android:icon="@drawable/ic_settings" android:icon="@drawable/ic_settings"
+1
View File
@@ -6,5 +6,6 @@
<color name="colorSecondary">#696969</color> <color name="colorSecondary">#696969</color>
<color name="colorSecondaryDark">#515151</color> <color name="colorSecondaryDark">#515151</color>
<color name="colorOnSecondary">#DFFFFFFF</color> <color name="colorOnSecondary">#DFFFFFFF</color>
<color name="colorAmoled">#000000</color>
<color name="colorAccent">#F93422</color> <color name="colorAccent">#F93422</color>
</resources> </resources>
+1
View File
@@ -6,5 +6,6 @@
<color name="colorSecondary">#999999</color> <color name="colorSecondary">#999999</color>
<color name="colorSecondaryDark">#888888</color> <color name="colorSecondaryDark">#888888</color>
<color name="colorOnSecondary">#111111</color> <color name="colorOnSecondary">#111111</color>
<color name="colorAmoled">#FFFFFF</color>
<color name="colorAccent">#F93422</color> <color name="colorAccent">#F93422</color>
</resources> </resources>
+1
View File
@@ -1,4 +1,5 @@
<resources> <resources>
<string name="app_name">NPS Browser</string> <string name="app_name">NPS Browser</string>
<string name="title_activity_settings">Settings</string> <string name="title_activity_settings">Settings</string>
<string name="search">Search</string>
</resources> </resources>
+1 -1
View File
@@ -10,7 +10,7 @@
<item name="colorSecondaryVariant">@color/colorSecondaryDark</item> <item name="colorSecondaryVariant">@color/colorSecondaryDark</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item> <item name="colorOnSecondary">@color/colorOnSecondary</item>
<item name="android:statusBarColor">@color/colorPrimary</item> <item name="android:statusBarColor">@color/colorAmoled</item>
<item name="alertDialogTheme">@style/NPSTheme.AlertDialog</item> <item name="alertDialogTheme">@style/NPSTheme.AlertDialog</item>
</style> </style>
+1 -1
View File
@@ -1,6 +1,6 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" <PreferenceScreen 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">
<PreferenceCategory android:title="Customization"> <PreferenceCategory android:title="Appearance">
<com.illusionware.npsbrowser.ThemePreference <com.illusionware.npsbrowser.ThemePreference
android:defaultValue="2" android:defaultValue="2"
+1 -1
View File
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.3.72' ext.kotlin_version = '1.4.10'
repositories { repositories {
google() google()
jcenter() jcenter()