mirror of
https://github.com/yggdrasil-network/crispa-android.git
synced 2024-11-13 22:11:03 +00:00
Merge branch 'peer_list_cache' of https://github.com/vikulin/yggdrasil-android
This commit is contained in:
commit
69e9999dfa
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,3 +15,4 @@
|
|||||||
/yggdrasil/yggdrasil-sources.jar
|
/yggdrasil/yggdrasil-sources.jar
|
||||||
/app/src/main/assets/yggdrasil-0.3.8-linux-arm64
|
/app/src/main/assets/yggdrasil-0.3.8-linux-arm64
|
||||||
/app/src/main/assets/yggdrasil-0.3.8-linux-armhf
|
/app/src/main/assets/yggdrasil-0.3.8-linux-armhf
|
||||||
|
/.idea/
|
||||||
|
@ -8,8 +8,8 @@ android {
|
|||||||
applicationId "io.github.chronosx88.yggdrasil"
|
applicationId "io.github.chronosx88.yggdrasil"
|
||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 5
|
versionCode 6
|
||||||
versionName "1.5"
|
versionName "1.6"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
setProperty("archivesBaseName", project.getParent().name+"-"+versionName)
|
setProperty("archivesBaseName", project.getParent().name+"-"+versionName)
|
||||||
}
|
}
|
||||||
@ -42,6 +42,10 @@ android {
|
|||||||
// but continue the build even when errors are found:
|
// but continue the build even when errors are found:
|
||||||
abortOnError false
|
abortOnError false
|
||||||
}
|
}
|
||||||
|
packagingOptions {
|
||||||
|
exclude 'META-INF/LICENSE'
|
||||||
|
exclude 'META-INF/NOTICE'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task ndkBuild(type: Exec) {
|
task ndkBuild(type: Exec) {
|
||||||
@ -59,16 +63,18 @@ dependencies {
|
|||||||
implementation project(path: ':yggdrasil')
|
implementation project(path: ':yggdrasil')
|
||||||
|
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
implementation "androidx.preference:preference-ktx:1.1.1"
|
implementation "androidx.preference:preference-ktx:1.1.1"
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7'
|
||||||
implementation 'com.google.android.material:material:1.3.0-alpha02'
|
implementation 'com.google.android.material:material:1.3.0-alpha04'
|
||||||
implementation 'com.google.code.gson:gson:2.8.6'
|
implementation 'com.google.code.gson:gson:2.8.6'
|
||||||
implementation 'com.hbb20:ccp:2.4.0'
|
implementation 'com.hbb20:ccp:2.4.0'
|
||||||
|
implementation 'com.vincentbrison.openlibraries.android:dualcache:3.1.1'
|
||||||
|
implementation 'com.vincentbrison.openlibraries.android:dualcache-jsonserializer:3.1.1'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.13.1'
|
||||||
androidTestImplementation 'androidx.test:runner:1.3.0'
|
androidTestImplementation 'androidx.test:runner:1.3.0'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||||
}
|
}
|
@ -15,9 +15,13 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton
|
|||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.reflect.TypeToken
|
import com.google.gson.reflect.TypeToken
|
||||||
import com.hbb20.CCPCountry
|
import com.hbb20.CCPCountry
|
||||||
|
import com.vincentbrison.openlibraries.android.dualcache.Builder
|
||||||
|
import com.vincentbrison.openlibraries.android.dualcache.SizeOf
|
||||||
|
import com.vincentbrison.openlibraries.android.dualcache.JsonSerializer
|
||||||
import io.github.chronosx88.yggdrasil.models.PeerInfo
|
import io.github.chronosx88.yggdrasil.models.PeerInfo
|
||||||
import io.github.chronosx88.yggdrasil.models.Status
|
import io.github.chronosx88.yggdrasil.models.Status
|
||||||
import io.github.chronosx88.yggdrasil.models.config.DropDownAdapter
|
import io.github.chronosx88.yggdrasil.models.config.DropDownAdapter
|
||||||
|
import io.github.chronosx88.yggdrasil.models.config.Peer
|
||||||
import io.github.chronosx88.yggdrasil.models.config.SelectPeerInfoListAdapter
|
import io.github.chronosx88.yggdrasil.models.config.SelectPeerInfoListAdapter
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2PeerInfoSet
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2PeerInfoSet
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.ping
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.ping
|
||||||
@ -39,6 +43,12 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val PEER_LIST_URL = "https://publicpeers.neilalexander.dev/publicnodes.json"
|
const val PEER_LIST_URL = "https://publicpeers.neilalexander.dev/publicnodes.json"
|
||||||
|
const val CACHE_NAME = "PEER_LIST_CACHE"
|
||||||
|
const val ONLINE_PEERINFO_LIST = "ONLINE_PEERINFO_LIST"
|
||||||
|
const val OFFLINE_PEERINFO_LIST = "OFFLINE_PEERINFO_LIST"
|
||||||
|
const val TEST_APP_VERSION = BuildConfig.VERSION_CODE;
|
||||||
|
const val RAM_MAX_SIZE = 100000
|
||||||
|
const val DISK_MAX_SIZE = 100000
|
||||||
}
|
}
|
||||||
|
|
||||||
fun downloadJson(link: String): String {
|
fun downloadJson(link: String): String {
|
||||||
@ -51,8 +61,6 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var isLoading = true;
|
|
||||||
|
|
||||||
var popup: PopupWindow? = null
|
var popup: PopupWindow? = null
|
||||||
var adapter: DropDownAdapter? = null
|
var adapter: DropDownAdapter? = null
|
||||||
|
|
||||||
@ -67,6 +75,13 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
var peerList = findViewById<ListView>(R.id.peerList)
|
var peerList = findViewById<ListView>(R.id.peerList)
|
||||||
var adapter = SelectPeerInfoListAdapter(this, arrayListOf(), mutableSetOf())
|
var adapter = SelectPeerInfoListAdapter(this, arrayListOf(), mutableSetOf())
|
||||||
peerList.adapter = adapter
|
peerList.adapter = adapter
|
||||||
|
var peerInfoListCache = Builder<List<PeerInfo>>(CACHE_NAME, TEST_APP_VERSION)
|
||||||
|
.enableLog()
|
||||||
|
.useReferenceInRam(RAM_MAX_SIZE, SizeOfPeerList())
|
||||||
|
.useSerializerInDisk(
|
||||||
|
DISK_MAX_SIZE, true,
|
||||||
|
JsonSerializer(ArrayList<PeerInfo>().javaClass), baseContext
|
||||||
|
).build();
|
||||||
|
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
try {
|
try {
|
||||||
@ -94,7 +109,12 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
try {
|
try {
|
||||||
var address = InetAddress.getByName(url.host)
|
var address = InetAddress.getByName(url.host)
|
||||||
var peerInfo =
|
var peerInfo =
|
||||||
PeerInfo(url.scheme, address, url.port, ccp.nameCode)
|
PeerInfo(
|
||||||
|
url.scheme,
|
||||||
|
address,
|
||||||
|
url.port,
|
||||||
|
ccp.nameCode
|
||||||
|
)
|
||||||
var ping = ping(address, url.port)
|
var ping = ping(address, url.port)
|
||||||
peerInfo.ping = ping
|
peerInfo.ping = ping
|
||||||
if(cp.contains(peerInfo)){
|
if(cp.contains(peerInfo)){
|
||||||
@ -114,14 +134,38 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(e: FileNotFoundException){
|
var allPeersList = adapter.getAllPeers()
|
||||||
|
var cachePeerInfoList = mutableListOf<PeerInfo>()
|
||||||
|
for(p in allPeersList){
|
||||||
|
if(p.ping<Int.MAX_VALUE){
|
||||||
|
cachePeerInfoList.add(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(cachePeerInfoList.size>0){
|
||||||
|
peerInfoListCache.put(ONLINE_PEERINFO_LIST, cachePeerInfoList.toList())
|
||||||
|
}
|
||||||
|
} catch (e: FileNotFoundException){
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
var onlinePeerInfoList = peerInfoListCache.get(ONLINE_PEERINFO_LIST)
|
||||||
|
if(onlinePeerInfoList!=null) {
|
||||||
|
for (peerInfo in onlinePeerInfoList) {
|
||||||
|
var ping = ping(peerInfo.address, peerInfo.port)
|
||||||
|
peerInfo.ping = ping
|
||||||
|
if (cp.contains(peerInfo)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
adapter.addItem(peerInfo)
|
||||||
|
if (adapter.count % 5 == 0) {
|
||||||
|
adapter.sort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var currentPeers = ArrayList(cp.sortedWith(compareBy { it.ping }))
|
var currentPeers = ArrayList(cp.sortedWith(compareBy { it.ping }))
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
adapter.addAll(0, currentPeers)
|
adapter.addAll(0, currentPeers)
|
||||||
isLoading = false
|
|
||||||
adapter.setLoading(isLoading)
|
|
||||||
}
|
}
|
||||||
} catch (e: Throwable){
|
} catch (e: Throwable){
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@ -150,7 +194,11 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
schemaInput.setOnClickListener { v->
|
schemaInput.setOnClickListener { v->
|
||||||
onClickSchemaList(v)
|
onClickSchemaList(v)
|
||||||
}
|
}
|
||||||
getPopupWindow(R.layout.spinner_item, resources.getStringArray(R.array.schemas), schemaInput);
|
getPopupWindow(
|
||||||
|
R.layout.spinner_item,
|
||||||
|
resources.getStringArray(R.array.schemas),
|
||||||
|
schemaInput
|
||||||
|
);
|
||||||
view.findViewById<com.hbb20.CountryCodePicker>(R.id.ccp).setCountryForNameCode(countryCode)
|
view.findViewById<com.hbb20.CountryCodePicker>(R.id.ccp).setCountryForNameCode(countryCode)
|
||||||
val ab: AlertDialog.Builder = AlertDialog.Builder(this)
|
val ab: AlertDialog.Builder = AlertDialog.Builder(this)
|
||||||
ab.setCancelable(true).setView(view)
|
ab.setCancelable(true).setView(view)
|
||||||
@ -180,7 +228,7 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
try {
|
try {
|
||||||
var ping = ping(pi.address, pi.port)
|
var ping = ping(pi.address, pi.port)
|
||||||
pi.ping = ping
|
pi.ping = ping
|
||||||
} catch(e: Throwable){
|
} catch (e: Throwable){
|
||||||
pi.ping = Int.MAX_VALUE
|
pi.ping = Int.MAX_VALUE
|
||||||
}
|
}
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
@ -235,9 +283,6 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
val saveButton = item
|
val saveButton = item
|
||||||
.actionView.findViewById<Button>(R.id.saveButton)
|
.actionView.findViewById<Button>(R.id.saveButton)
|
||||||
saveButton.setOnClickListener {
|
saveButton.setOnClickListener {
|
||||||
if(isLoading){
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
val result = Intent(this, MainActivity::class.java)
|
val result = Intent(this, MainActivity::class.java)
|
||||||
var adapter = findViewById<ListView>(R.id.peerList).adapter as SelectPeerInfoListAdapter
|
var adapter = findViewById<ListView>(R.id.peerList).adapter as SelectPeerInfoListAdapter
|
||||||
val selectedPeers = adapter.getSelectedPeers()
|
val selectedPeers = adapter.getSelectedPeers()
|
||||||
@ -248,3 +293,29 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SizeOfPeerList: SizeOf<List<PeerInfo>> {
|
||||||
|
|
||||||
|
override fun sizeOf(obj: List<PeerInfo>): Int{
|
||||||
|
var size = 0
|
||||||
|
for (o in obj) {
|
||||||
|
if (o.address != null) {
|
||||||
|
size += o.address.toString().length * 2
|
||||||
|
}
|
||||||
|
if (o.hostName != null) {
|
||||||
|
size += o.hostName.length * 2
|
||||||
|
}
|
||||||
|
if (o.schema != null) {
|
||||||
|
size += o.schema.length * 2
|
||||||
|
}
|
||||||
|
if (o.countryCode != null) {
|
||||||
|
size += o.countryCode!!.length * 2
|
||||||
|
}
|
||||||
|
size += 4
|
||||||
|
size += 4
|
||||||
|
size += 1
|
||||||
|
}
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -18,7 +18,6 @@ class SelectPeerInfoListAdapter(
|
|||||||
currentPeers: MutableSet<PeerInfo>
|
currentPeers: MutableSet<PeerInfo>
|
||||||
) : ArrayAdapter<PeerInfo?> (context, 0, allPeers) {
|
) : ArrayAdapter<PeerInfo?> (context, 0, allPeers) {
|
||||||
|
|
||||||
private var isLoading = true
|
|
||||||
private val mContext: Context = context
|
private val mContext: Context = context
|
||||||
private var allPeers: MutableList<PeerInfo> = allPeers as MutableList<PeerInfo>
|
private var allPeers: MutableList<PeerInfo> = allPeers as MutableList<PeerInfo>
|
||||||
private var currentPeers: MutableSet<PeerInfo> = currentPeers
|
private var currentPeers: MutableSet<PeerInfo> = currentPeers
|
||||||
@ -75,6 +74,10 @@ class SelectPeerInfoListAdapter(
|
|||||||
return currentPeers
|
return currentPeers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getAllPeers(): List<PeerInfo> {
|
||||||
|
return allPeers
|
||||||
|
}
|
||||||
|
|
||||||
fun addItem(peerInfo: PeerInfo){
|
fun addItem(peerInfo: PeerInfo){
|
||||||
allPeers.add(peerInfo)
|
allPeers.add(peerInfo)
|
||||||
}
|
}
|
||||||
@ -95,10 +98,6 @@ class SelectPeerInfoListAdapter(
|
|||||||
this.notifyDataSetChanged()
|
this.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setLoading(loading: Boolean){
|
|
||||||
this.isLoading = loading
|
|
||||||
}
|
|
||||||
|
|
||||||
class PeerInfoHolder {
|
class PeerInfoHolder {
|
||||||
lateinit var checkbox: CheckBox
|
lateinit var checkbox: CheckBox
|
||||||
lateinit var countryFlag: ImageView
|
lateinit var countryFlag: ImageView
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
// 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()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
classpath 'com.android.tools.build:gradle:4.1.1'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
Loading…
Reference in New Issue
Block a user