more changes

This commit is contained in:
Tucan444 2021-04-21 11:34:03 +02:00
parent d14dd7c1fd
commit 8737a5a471
31 changed files with 1647 additions and 126 deletions

@ -1,6 +1,6 @@
<resources> <resources>
<!-- <!--
TODO: Before you run your application, you need a Google Maps API key. Before you run your application, you need a Google Maps API key.
To get one, follow this link, follow the directions and press "Create" at the end: To get one, follow this link, follow the directions and press "Create" at the end:

@ -7,11 +7,11 @@ import android.os.Environment
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import okhttp3.* import java.io.File
import org.json.JSONArray import java.io.FileInputStream
import java.io.*
import java.nio.channels.FileChannel import java.nio.channels.FileChannel
import java.nio.charset.Charset import java.nio.charset.Charset
import java.util.*
// for showing messages // for showing messages
@ -85,6 +85,18 @@ fun Context.getStringFromSharedPreferences(accessKey: String, preferencesFilenam
return "" return ""
} }
// Other
fun Context.getRandomGenerator(seedString: String): Random {
var n: Long = 0
for (element in seedString) {
n += element.toInt()
}
println(n)
return Random(n)
}
// Activity extensions // Activity extensions
fun Activity.askToQuit() { fun Activity.askToQuit() {

@ -48,7 +48,6 @@ class MainActivity : AppCompatActivity() {
askToQuit() askToQuit()
} }
is infoFragment -> { is infoFragment -> {
println(CustomBackstackVariables.infoFragmentBackDestination)
when (CustomBackstackVariables.infoFragmentBackDestination) { when (CustomBackstackVariables.infoFragmentBackDestination) {
"exploreFragment" -> { currentlyShownFragment.goExploreFragment() } "exploreFragment" -> { currentlyShownFragment.goExploreFragment() }
"mapFragment" -> {currentlyShownFragment.goMapFragment()} "mapFragment" -> {currentlyShownFragment.goMapFragment()}
@ -78,6 +77,11 @@ class MainActivity : AppCompatActivity() {
windowManager.defaultDisplay.getMetrics(displayMetrics) windowManager.defaultDisplay.getMetrics(displayMetrics)
ScreenParameters.height = displayMetrics.heightPixels ScreenParameters.height = displayMetrics.heightPixels
ScreenParameters.width = displayMetrics.widthPixels ScreenParameters.width = displayMetrics.widthPixels
val savedBaseUrl = this.getStringFromSharedPreferences("baseUrlSave")
if (savedBaseUrl != "") {
ServerManagement.baseUrl = savedBaseUrl
}
} }
override fun onResume() { override fun onResume() {
@ -90,11 +94,12 @@ class MainActivity : AppCompatActivity() {
val names = json.currentJsonObject!!.names() val names = json.currentJsonObject!!.names()
try { try {
names?.let {
mainFragmentHost.childFragmentManager.fragments[0]?.let { mainFragmentHost.childFragmentManager.fragments[0]?.let {
if (it is homeFragment) { if (it is homeFragment) {
LabeledValuesSupplier.wipeData() LabeledValuesSupplier.wipeData()
for (n in 0 until names!!.length()) { for (n in 0 until names.length()) {
val labeledValue = LabeledValue(names[n].toString(), json.getAttributeContent(names[n].toString())) val labeledValue = LabeledValue(names[n].toString(), json.getAttributeContent(names[n].toString()))
if (!LabeledValuesSupplier.checkIfContains(labeledValue)) { if (!LabeledValuesSupplier.checkIfContains(labeledValue)) {
LabeledValuesSupplier.appendLabeledValue(labeledValue) LabeledValuesSupplier.appendLabeledValue(labeledValue)
@ -111,6 +116,7 @@ class MainActivity : AppCompatActivity() {
} }
} }
} }
}
} catch (e: Throwable) { println("[debug] Exception in main activity, sensors connection : $e") } } catch (e: Throwable) { println("[debug] Exception in main activity, sensors connection : $e") }
} }
@ -122,7 +128,7 @@ class MainActivity : AppCompatActivity() {
// getting other needed information // getting other needed information
val dataReceiver2: (String) -> Unit = {data1: String -> val dataReceiver2: (String) -> Unit = {data1: String ->
var json = JsonManager(this, data1) var json = JsonManager(this, data1)
json = JsonManager(this, json.findJsonObjectByAttribute("ID", data0.toInt()), "JSONObject") json = JsonManager(this, json.findJsonObjectByAttribute("ID", data0.toInt()), "JSONObject") // todo doesnt return correct result
val positionsList = json.getAttributeContent("location").split(",") val positionsList = json.getAttributeContent("location").split(",")
MapManagement.connectedServerPosition = LatLng(positionsList[0].toDouble(), positionsList[1].toDouble()) MapManagement.connectedServerPosition = LatLng(positionsList[0].toDouble(), positionsList[1].toDouble())
} }

@ -5,6 +5,8 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.example.wikispot.ChatManagement
import com.example.wikispot.GeneralVariables
import com.example.wikispot.R import com.example.wikispot.R
import com.example.wikispot.modelsForAdapters.Message import com.example.wikispot.modelsForAdapters.Message
import kotlinx.android.synthetic.main.message.view.* import kotlinx.android.synthetic.main.message.view.*
@ -19,8 +21,20 @@ class ChatMessagesAdapter(private val context: Context, private val messages: Ar
fun setData(message: Message?, pos: Int) { fun setData(message: Message?, pos: Int) {
message?.let { message?.let {
itemView.message_author_text.text = message.author itemView.message_author_text.text = message.senderName
itemView.message_content_text.text = message.content itemView.message_content_text.text = message.content
if (GeneralVariables.id == message.senderId) {
itemView.message_author_text.textAlignment = View.TEXT_ALIGNMENT_TEXT_END
itemView.message_content_text.textAlignment = View.TEXT_ALIGNMENT_TEXT_END
}
for (n in 0 until ChatManagement.lastNames.length()) {
if (ChatManagement.lastNames[n] == message.senderId) {
itemView.message_author_text.textAlignment = View.TEXT_ALIGNMENT_TEXT_END
itemView.message_content_text.textAlignment = View.TEXT_ALIGNMENT_TEXT_END
itemView.message_author_text.text = GeneralVariables.name
}
}
} }
this.message = message this.message = message

File diff suppressed because it is too large Load Diff

@ -1,16 +1,20 @@
package com.example.wikispot.fragments package com.example.wikispot.fragments
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.View import android.view.View
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.example.wikispot.R import com.example.wikispot.*
import com.example.wikispot.ServerManagement
import com.example.wikispot.adapters.ChatMessagesAdapter import com.example.wikispot.adapters.ChatMessagesAdapter
import com.example.wikispot.adapters.FileViewsAdapter import com.example.wikispot.databases.NamesDatabase
import com.example.wikispot.modelClasses.JsonManager
import com.example.wikispot.modelsForAdapters.Message
import com.example.wikispot.modelsForAdapters.MessagesSupplier import com.example.wikispot.modelsForAdapters.MessagesSupplier
import kotlinx.android.synthetic.main.fragment_chat.* import kotlinx.android.synthetic.main.fragment_chat.*
import kotlinx.android.synthetic.main.fragment_info.* import okhttp3.*
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import org.json.JSONArray
import java.io.IOException
class chatFragment : Fragment(R.layout.fragment_chat) { class chatFragment : Fragment(R.layout.fragment_chat) {
@ -19,20 +23,93 @@ class chatFragment : Fragment(R.layout.fragment_chat) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
updateRecyclerView() updateRecyclerView()
sendMessageBtn.setOnClickListener {
GeneralVariables.id?.let {
if (userMessageText.text.toString() != "" ) {
val message = Message(GeneralVariables.id!!, userMessageText.text.toString(), "waiting")
MessagesSupplier.appendMessage(message)
userMessageText.setText("")
val messagePostThread = Thread(MessagePost(message))
messagePostThread.start()
updateRecyclerView()
} else {
requireContext().showToast("sending empty messages is not permitted")
}
}
}
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
loadNamesCache()
val dataReceiver: (String) -> Unit = {data: String -> val dataReceiver: (String) -> Unit = { data: String ->
println("[debug][chat connection] data: $data") val json = JsonManager(requireContext(), data, "JSONObject")
try {
when (json.getAttributeContent("source")) {
"messages/register" -> {
GeneralVariables.id = json.getAttributeContentByPath("data/0")
val r = requireContext().getRandomGenerator(GeneralVariables.id!!)
GeneralVariables.name = "${NamesDatabase.names[r.nextInt(NamesDatabase.names.size)]} - ${r.nextInt(9999).toString()}"
json.getAttributeContent("data")
json.getAttributeContent("1")
val length = json.currentJsonAttribute1!!.length()
json.clearSelectedAttribute()
for (i in 0 until length) {
val jsonOfMessage = JsonManager(requireContext(), json.getAttributeContentByPath("data/1/$i"), "JSONObject")
val message = Message(jsonOfMessage.getAttributeContent("sender"),
jsonOfMessage.getAttributeContent("message"),
jsonOfMessage.getAttributeContent("timestamp"))
if (!MessagesSupplier.checkIfContains(message)) {
MessagesSupplier.appendMessage(message)
updateRecyclerView()
}
}
}
"messages/get" -> {
json.getAttributeContent("data")
val length = json.currentJsonAttribute1!!.length()
json.clearSelectedAttribute()
for (i in 0 until length) {
println("message at index n: ${json.getAttributeContentByPath("data/$i")}")
val jsonOfMessage = JsonManager(requireContext(), json.getAttributeContentByPath("data/$i"), "JSONObject")
val message = Message(jsonOfMessage.getAttributeContent("sender"),
jsonOfMessage.getAttributeContent("message"),
jsonOfMessage.getAttributeContent("timestamp"))
val lastMessageSentIndex = MessagesSupplier.getIndexOfLastMessageFromSelf()
if (message.senderId != GeneralVariables.id) {
if (!MessagesSupplier.checkIfContains(message)) {
MessagesSupplier.appendMessage(message)
updateRecyclerView()
}
} else {
lastMessageSentIndex?.let {
MessagesSupplier.messages[lastMessageSentIndex]!!.timestamp = jsonOfMessage.getAttributeContent("timestamp")
}
}
}
}
}
} catch (e: Throwable) { println("[debug][chat fragment] Exception: $e") }
} }
ServerManagement.serverManager.addReceiverConnection(dataReceiver, requireContext(), "chatConnection", 0, ServerManagement.chat_keyword) ServerManagement.serverManager.addChatConnection(dataReceiver, requireContext(), "chatConnection")
} }
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
saveNamesCache()
ServerManagement.serverManager.deleteConnection("chatConnection") ServerManagement.serverManager.deleteConnection("chatConnection")
} }
@ -46,9 +123,74 @@ class chatFragment : Fragment(R.layout.fragment_chat) {
val adapter = context?.let { ChatMessagesAdapter(it, MessagesSupplier.messages) } val adapter = context?.let { ChatMessagesAdapter(it, MessagesSupplier.messages) }
chat_messages_recycler_view.adapter = adapter chat_messages_recycler_view.adapter = adapter
chat_messages_recycler_view.scrollToPosition(MessagesSupplier.messages.size - 1)
} }
} catch (e: Throwable) { println("[debug] e5 Exception: $e") } } catch (e: Throwable) { println("[debug] e5 Exception: $e") }
} }
inner class MessagePost(private val message: Message): Runnable {
override fun run() {
val urlBuilder: HttpUrl.Builder = "${ServerManagement.baseUrl}messages/post".toHttpUrlOrNull()!!.newBuilder()
.addQueryParameter("m_sender", message.senderId)
.addQueryParameter("message", message.content)
val url: String = urlBuilder.build().toString()
val formBody: FormBody = FormBody.Builder().build()
val request: Request = Request.Builder()
.url(url)
.post(formBody)
.build()
val client = OkHttpClient()
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
response.body?.let {
val receivedString = response.body!!.string()
println("[debug][message post] received string from post request: $receivedString")
}
}
override fun onFailure(call: Call, e: IOException) {
println("Request Failed")
println(e)
}
})
}
}
// loading and saving last names
private fun loadNamesCache() {
val namesCache = requireContext().getStringFromSharedPreferences("namesCache", "chatPreferences")
if (namesCache != "") {
ChatManagement.lastNames = JSONArray(namesCache)
}
}
private fun saveNamesCache() {
GeneralVariables.id?.let {
ChatManagement.lastNames.let {
val namesCache = JSONArray()
var subtractAmount = it.length()
if (it.length() > (ChatManagement.numberOfNamesToCache - 1)) {
subtractAmount = ChatManagement.numberOfNamesToCache - 1
}
for (i in it.length() - subtractAmount until it.length()) {
namesCache.put(it[i])
}
namesCache.put(GeneralVariables.id)
requireContext().saveString("namesCache", namesCache.toString(), "chatPreferences")
}
}
}
} }

@ -6,11 +6,9 @@ import android.os.Bundle
import android.view.View import android.view.View
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.Navigation import androidx.navigation.Navigation
import com.example.wikispot.IntentsKeys import com.example.wikispot.*
import com.example.wikispot.R
import com.example.wikispot.ServerManagement
import com.example.wikispot.activities.MainActivity import com.example.wikispot.activities.MainActivity
import com.example.wikispot.modelClasses.JsonManager import com.example.wikispot.modelsForAdapters.MessagesSupplier
import kotlinx.android.synthetic.main.fragment_debug.* import kotlinx.android.synthetic.main.fragment_debug.*
@ -34,8 +32,9 @@ class debugFragment : Fragment(R.layout.fragment_debug) {
editTextIp.setText(ServerManagement.baseUrl) editTextIp.setText(ServerManagement.baseUrl)
changeIpBtn.setOnClickListener { changeUrlBtn.setOnClickListener {
ServerManagement.baseUrl = editTextIp.text.toString() ServerManagement.baseUrl = editTextIp.text.toString()
requireContext().saveString("baseUrlSave", editTextIp.text.toString())
restartAppPartially() restartAppPartially()
} }
@ -43,6 +42,10 @@ class debugFragment : Fragment(R.layout.fragment_debug) {
restartAppPartially() restartAppPartially()
} }
closeAppBtn.setOnClickListener {
activity?.finish()
}
} }
private fun restartAppPartially() { private fun restartAppPartially() {
@ -51,6 +54,8 @@ class debugFragment : Fragment(R.layout.fragment_debug) {
intent.putExtra(IntentsKeys.startFragment, "debugFragment") intent.putExtra(IntentsKeys.startFragment, "debugFragment")
ServerManagement.serverManager.clearConnections() ServerManagement.serverManager.clearConnections()
MessagesSupplier.wipeData()
GeneralVariables.id = null
startActivity(intent) startActivity(intent)
activity?.finish() activity?.finish()

@ -4,6 +4,7 @@ import android.graphics.Bitmap
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import com.example.wikispot.R import com.example.wikispot.R
import com.example.wikispot.ServerManagement import com.example.wikispot.ServerManagement
import com.example.wikispot.modelClasses.JsonManager import com.example.wikispot.modelClasses.JsonManager
@ -18,6 +19,10 @@ class homeFragment : Fragment(R.layout.fragment_home) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
loadCache() loadCache()
chatBtn.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.homeFragment_to_chatFragment)
}
} }
override fun onResume() { override fun onResume() {

@ -1,6 +1,7 @@
package com.example.wikispot.modelClasses package com.example.wikispot.modelClasses
import android.content.Context import android.content.Context
import com.example.wikispot.GeneralVariables
import com.example.wikispot.getStringFromSharedPreferences import com.example.wikispot.getStringFromSharedPreferences
import com.example.wikispot.saveString import com.example.wikispot.saveString
import com.example.wikispot.showToast import com.example.wikispot.showToast
@ -72,7 +73,8 @@ data class JsonManager(private val context: Context, val data: String, val input
} }
} }
} }
} else if (currentJsonAttribute1 != null) { }
if (currentJsonAttribute1 != null) {
try { try {
currentJsonAttribute0 = currentJsonAttribute1!!.getJSONObject(name.toInt()) currentJsonAttribute0 = currentJsonAttribute1!!.getJSONObject(name.toInt())
return currentJsonAttribute0.toString() return currentJsonAttribute0.toString()
@ -117,7 +119,7 @@ data class JsonManager(private val context: Context, val data: String, val input
} }
} }
return "" return GeneralVariables.variableMissingKeyword
} }
fun getAttributeContentByPath(path: String): String { fun getAttributeContentByPath(path: String): String {
@ -136,7 +138,7 @@ data class JsonManager(private val context: Context, val data: String, val input
// loading back saved json attributes // loading back saved json attributes
currentJsonAttribute0 = currentJsonAttributesBackup[0] as JSONObject? currentJsonAttribute0 = currentJsonAttributesBackup[0] as JSONObject?
currentJsonAttribute1 = currentJsonAttributesBackup[1] as JSONArray? currentJsonAttribute1 = currentJsonAttributesBackup[1] as JSONArray?
return "" return GeneralVariables.variableMissingKeyword
} }
} }
@ -183,7 +185,7 @@ data class JsonManager(private val context: Context, val data: String, val input
val attributeContent = getAttributeContentByPath(attributePath) val attributeContent = getAttributeContentByPath(attributePath)
if (attributeContent != "null") { if (attributeContent != GeneralVariables.variableMissingKeyword) {
if (attributeContent == value.toString()) { if (attributeContent == value.toString()) {
return currentJsonObject.toString() return currentJsonObject.toString()

@ -4,28 +4,32 @@ import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.widget.TextView import android.widget.TextView
import com.example.wikispot.GeneralVariables
import com.example.wikispot.ScreenParameters
import com.example.wikispot.ServerManagement import com.example.wikispot.ServerManagement
import com.example.wikispot.modelsForAdapters.MessagesSupplier
import com.github.barteksc.pdfviewer.PDFView import com.github.barteksc.pdfviewer.PDFView
import kotlinx.android.synthetic.main.file_view.view.*
import okhttp3.* import okhttp3.*
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import java.io.IOException import java.io.IOException
import java.io.InputStream
class ServerManager { class ServerManager {
private var receiverConnections = mutableListOf<ReceiverConnection>() private var receiverConnections = mutableListOf<ReceiverConnection>()
private var viewConnections = mutableListOf<ViewConnection>() private var viewConnections = mutableListOf<ViewConnection>()
private var chatConnections = mutableListOf<ChatConnection>()
// single time requests // single time requests
fun getData(dataReceiver: (String) -> Unit, context: Context, serverId: Int, path: String, attributePath: String="", numberOfAttempts: Int=2) { fun getData(dataReceiver: (String) -> Unit, context: Context, serverId: Int, path: String, attributePath: String = "", numberOfAttempts: Int = 2) {
val dataRequestThread = Thread(DataRequest(dataReceiver, context, serverId, path, attributePath, numberOfAttempts)) val dataRequestThread = Thread(DataRequest(dataReceiver, context, serverId, path, attributePath, numberOfAttempts))
dataRequestThread.start() dataRequestThread.start()
} }
inner class DataRequest(val dataReceiver: (String) -> Unit, val context: Context, val serverId: Int, val path: String="", val attributePath: String, private val numberOfAttempts: Int=2): Runnable{ inner class DataRequest(val dataReceiver: (String) -> Unit, val context: Context, val serverId: Int, val path: String = "", val attributePath: String, private val numberOfAttempts: Int = 2): Runnable{
override fun run() { override fun run() {
for (n in 0 until numberOfAttempts) { for (n in 0 until numberOfAttempts) {
var url = "${ServerManagement.baseUrl}devices_list" var url = "${ServerManagement.baseUrl}devices_list"
@ -65,7 +69,7 @@ class ServerManager {
} }
} }
if(attributePath != "") { if (attributePath != "") {
dataReceiver(jsonManager.getAttributeContentByPath(attributePath)) dataReceiver(jsonManager.getAttributeContentByPath(attributePath))
} else { } else {
dataReceiver(jsonManager.currentJsonObject.toString()) dataReceiver(jsonManager.currentJsonObject.toString())
@ -77,7 +81,7 @@ class ServerManager {
val jsonManager = JsonManager(context, receivedString, "JSONObject") val jsonManager = JsonManager(context, receivedString, "JSONObject")
if(attributePath != "") { if (attributePath != "") {
dataReceiver(jsonManager.getAttributeContentByPath(attributePath)) dataReceiver(jsonManager.getAttributeContentByPath(attributePath))
} else { } else {
dataReceiver(jsonManager.currentJsonObject.toString()) dataReceiver(jsonManager.currentJsonObject.toString())
@ -115,7 +119,12 @@ class ServerManager {
try { try {
val inputStream = java.net.URL(url).openStream() val inputStream = java.net.URL(url).openStream()
val bitmap = BitmapFactory.decodeStream(inputStream) var bitmap = BitmapFactory.decodeStream(inputStream)
if (bitmap.width > ScreenParameters.width) {
val ratio = bitmap.height.toFloat() / bitmap.width.toFloat()
bitmap = Bitmap.createScaledBitmap(bitmap, ScreenParameters.width, (ScreenParameters.width * ratio).toInt(), false)
}
imageReceiver(bitmap) imageReceiver(bitmap)
break break
@ -128,12 +137,12 @@ class ServerManager {
} }
} }
fun loadPdfView(view: PDFView, url: String, swipeHorizontal: Boolean=false) { fun loadPdfView(view: PDFView, url: String, swipeHorizontal: Boolean = false) {
val pdfLoadingRequestThread = Thread(PdfLoadingRequest(view, url, swipeHorizontal)) val pdfLoadingRequestThread = Thread(PdfLoadingRequest(view, url, swipeHorizontal))
pdfLoadingRequestThread.start() pdfLoadingRequestThread.start()
} }
inner class PdfLoadingRequest(val view: PDFView, val url: String, private val swipeHorizontal: Boolean=false): Runnable { inner class PdfLoadingRequest(val view: PDFView, val url: String, private val swipeHorizontal: Boolean = false): Runnable {
override fun run() { override fun run() {
val inputStream = java.net.URL(url).openStream() val inputStream = java.net.URL(url).openStream()
view.post { view.post {
@ -153,15 +162,23 @@ class ServerManager {
} catch (e: Throwable) { println("In clearConnections: $e") } } catch (e: Throwable) { println("In clearConnections: $e") }
} }
receiverConnections = mutableListOf() receiverConnections = mutableListOf()
for (i in 0 until viewConnections.size) { for (i in 0 until viewConnections.size) {
try { try {
viewConnections[i].running = false viewConnections[i].running = false
} catch (e: Throwable) { println("In clearConnections: $e") } } catch (e: Throwable) { println("In clearConnections: $e") }
} }
viewConnections = mutableListOf() viewConnections = mutableListOf()
for (i in 0 until chatConnections.size) {
try {
chatConnections[i].running = false
} catch (e: Throwable) { println("In clearConnections: $e") }
}
chatConnections = mutableListOf()
} }
fun checkIfConnectionAlreadyExists(connectionName: String, connectionType: String="any"): Boolean{ fun checkIfConnectionAlreadyExists(connectionName: String, connectionType: String = "any"): Boolean{
if ((connectionType == "any") or (connectionType == "receiver")) { if ((connectionType == "any") or (connectionType == "receiver")) {
for (n in 0 until receiverConnections.size) { for (n in 0 until receiverConnections.size) {
if (receiverConnections[n].connectionName == connectionName) { if (receiverConnections[n].connectionName == connectionName) {
@ -176,11 +193,18 @@ class ServerManager {
} }
} }
} }
if ((connectionType == "any") or (connectionType == "chat")) {
for (n in 0 until chatConnections.size) {
if (chatConnections[n].connectionName == connectionName) {
return true
}
}
}
return false return false
} }
fun deleteConnection(connectionName: String, connectionType: String="any") { // other types are any, activity and view fun deleteConnection(connectionName: String, connectionType: String = "any") { // other types are any, activity and view
if ((connectionType == "any") or (connectionType == "receiver")) { if ((connectionType == "any") or (connectionType == "receiver")) {
for (i in 0 until receiverConnections.size) { // checking in connections for (i in 0 until receiverConnections.size) { // checking in connections
try { try {
@ -202,13 +226,24 @@ class ServerManager {
} catch (e: Throwable) { println("In deleteConnection: $e") } } catch (e: Throwable) { println("In deleteConnection: $e") }
} }
} }
if ((connectionType == "any") or (connectionType == "chat")) {
for (i in 0 until chatConnections.size) { // checking in connections
try {
if (chatConnections[i].connectionName == connectionName) {
chatConnections[i].running = false
chatConnections.removeAt(i)
}
} catch (e: Throwable) { println("In deleteConnection: $e") }
}
}
} }
fun addReceiverConnection(dataReceiver: (String) -> Unit, context: Context, connectionName: String, serverId: Int, path: String="", attributePath: String="", waitTime: Long=ServerManagement.receiverConnectionOnCheckWait) { fun addReceiverConnection(dataReceiver: (String) -> Unit, context: Context, connectionName: String, serverId: Int, path: String = "", attributePath: String = "", waitTime: Long = ServerManagement.receiverConnectionOnCheckWait) {
receiverConnections.add(ReceiverConnection(dataReceiver, context, connectionName, serverId, path, attributePath, waitTime)) receiverConnections.add(ReceiverConnection(dataReceiver, context, connectionName, serverId, path, attributePath, waitTime))
} }
inner class ReceiverConnection(val dataReceiver: (String) -> Unit, val context: Context, val connectionName: String, val serverId: Int, val path: String="", val attributePath: String, val waitTime: Long) { inner class ReceiverConnection(val dataReceiver: (String) -> Unit, val context: Context, val connectionName: String, val serverId: Int, val path: String = "", val attributePath: String, val waitTime: Long) {
var running = true var running = true
@ -257,7 +292,7 @@ class ServerManager {
} }
} }
if(attributePath != "") { if (attributePath != "") {
dataReceiver(jsonManager.getAttributeContentByPath(attributePath)) dataReceiver(jsonManager.getAttributeContentByPath(attributePath))
} else { } else {
dataReceiver(jsonManager.currentJsonObject.toString()) dataReceiver(jsonManager.currentJsonObject.toString())
@ -269,7 +304,7 @@ class ServerManager {
val jsonManager = JsonManager(context, receivedString, "JSONObject") val jsonManager = JsonManager(context, receivedString, "JSONObject")
if(attributePath != "") { if (attributePath != "") {
dataReceiver(jsonManager.getAttributeContentByPath(attributePath)) dataReceiver(jsonManager.getAttributeContentByPath(attributePath))
} else { } else {
dataReceiver(jsonManager.currentJsonObject.toString()) dataReceiver(jsonManager.currentJsonObject.toString())
@ -297,11 +332,11 @@ class ServerManager {
} }
fun addViewConnection(context: Context, view: TextView, connectionName: String, serverId: Int, path: String="", attributePath: String="") { fun addViewConnection(context: Context, view: TextView, connectionName: String, serverId: Int, path: String = "", attributePath: String = "") {
viewConnections.add(ViewConnection(context, view, connectionName, serverId, path, attributePath)) viewConnections.add(ViewConnection(context, view, connectionName, serverId, path, attributePath))
} }
inner class ViewConnection(val context: Context, val view: TextView, val connectionName: String, val serverId: Int, val path: String="", var attributePath: String) { inner class ViewConnection(val context: Context, val view: TextView, val connectionName: String, val serverId: Int, val path: String = "", var attributePath: String) {
var running = true var running = true
@ -351,7 +386,7 @@ class ServerManager {
} }
} }
if(attributePath != "") { if (attributePath != "") {
view.post { view.post {
view.text = jsonManager.getAttributeContentByPath(attributePath) view.text = jsonManager.getAttributeContentByPath(attributePath)
} }
@ -367,7 +402,7 @@ class ServerManager {
val jsonManager = JsonManager(context, receivedString, "JSONObject") val jsonManager = JsonManager(context, receivedString, "JSONObject")
if(attributePath != "") { if (attributePath != "") {
view.post { view.post {
view.text = jsonManager.getAttributeContentByPath(attributePath) view.text = jsonManager.getAttributeContentByPath(attributePath)
} }
@ -401,4 +436,102 @@ class ServerManager {
} }
fun addChatConnection(dataReceiver: (String) -> Unit, context: Context, connectionName: String) {
chatConnections.add(ChatConnection(dataReceiver, context, connectionName))
}
inner class ChatConnection(val dataReceiver: (String) -> Unit, val context: Context, val connectionName: String) {
var running = true
init {
val checkingServerDataThread = Thread(CheckingServerData())
checkingServerDataThread.start()
}
inner class CheckingServerData : Runnable {
override fun run() {
while (running) {
if (GeneralVariables.id == null) {
val url = "${ServerManagement.baseUrl}messages/register"
println(url)
val request = Request.Builder().url(url).build()
val client = OkHttpClient()
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
response.body?.let {
val receivedString = response.body!!.string()
if (receivedString == "Internal Server Error") {
return
}
val returnJsonObject = JSONObject()
returnJsonObject.put("source", "messages/register")
returnJsonObject.put("data", JSONArray(receivedString))
dataReceiver(returnJsonObject.toString())
}
}
override fun onFailure(call: Call, e: IOException) {
println("Request Failed")
println(e)
}
})
} else {
var timestamp = "0"
if (MessagesSupplier.messages.isNotEmpty()) {
val messagesReversed = MessagesSupplier.messages.reversed()
for (i in messagesReversed.indices) {
if (messagesReversed[i]!!.timestamp != "waiting") {
timestamp = messagesReversed[i]!!.timestamp
break
}
}
}
val urlBuilder: HttpUrl.Builder = "${ServerManagement.baseUrl}messages/get".toHttpUrlOrNull()!!.newBuilder()
urlBuilder.addQueryParameter("timestamp", timestamp)
val url: String = urlBuilder.build().toString()
val request: Request = Request.Builder()
.url(url)
.build()
val client = OkHttpClient()
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
response.body?.let {
val receivedString = response.body!!.string()
if (receivedString == "Internal Server Error") {
return
}
val returnJsonObject = JSONObject()
returnJsonObject.put("source", "messages/get")
returnJsonObject.put("data", JSONArray(receivedString))
dataReceiver(returnJsonObject.toString())
}
}
override fun onFailure(call: Call, e: IOException) {
println("Request Failed")
println(e)
}
})
}
Thread.sleep(ServerManagement.chatConnectionOnCheckWait)
}
}
}
}
} }

@ -11,7 +11,7 @@ import org.json.JSONArray
data class PlacePreview(var title: String, var description: String, var location: String? = null, var img: Bitmap? = null, val id: Int?=null) { data class PlacePreview(var title: String, var description: String, var location: String? = null, var img: Bitmap? = null, val id: Int?=null) {
init { init {
val words = description.split(" ") val words = description.split(" ", "\n")
description = "" description = ""
var lastLine = "" var lastLine = ""
@ -35,11 +35,7 @@ object PlaceSupplier {
var controlJson: JsonManagerLite? = null var controlJson: JsonManagerLite? = null
var places = arrayOf<PlacePreview?>( var places = arrayOf<PlacePreview?>()
PlacePreview("River", "", "39.94071648123733,-85.9346308193051", null, 12),
PlacePreview("Velky Manin", "", "49.12590793522579,18.49571849264312", null, 16),
PlacePreview("Klapy", "", "49.161527643132175,18.41231657316252", null, 18)
)
fun appendPlace(place: PlacePreview) { fun appendPlace(place: PlacePreview) {
val array = places.copyOf(places.size + 1) val array = places.copyOf(places.size + 1)
@ -83,7 +79,6 @@ object PlaceSupplier {
val jsonManager = JsonManager(context, save) val jsonManager = JsonManager(context, save)
for (n in 0 until jsonManager.getLengthOfJsonArray()) { for (n in 0 until jsonManager.getLengthOfJsonArray()) {
val savedData = jsonManager.jsonArray?.get(n).toString().split("|||||") val savedData = jsonManager.jsonArray?.get(n).toString().split("|||||")
println("[debug] saved data is $savedData")
val place = PlacePreview(savedData[0], savedData[1], savedData[2], null, savedData[3].toInt()) val place = PlacePreview(savedData[0], savedData[1], savedData[2], null, savedData[3].toInt())
if (!checkIfContains(place)) { if (!checkIfContains(place)) {
appendPlace(place) appendPlace(place)

@ -1,6 +1,29 @@
package com.example.wikispot.modelsForAdapters package com.example.wikispot.modelsForAdapters
data class Message(val author: String, val content: String) import com.example.wikispot.GeneralVariables
import com.example.wikispot.databases.NamesDatabase
import java.util.*
data class Message(var senderId: String, val content: String, var timestamp: String="0") {
var senderName: String
init {
val r = getRandomGenerator(senderId)
senderName = "${NamesDatabase.names[r.nextInt(NamesDatabase.names.size)]} - ${r.nextInt(9999).toString()}"
}
private fun getRandomGenerator(seedString: String): Random {
var n: Long = 0
for (element in seedString) {
n += element.toInt()
}
return Random(n)
}
}
object MessagesSupplier { object MessagesSupplier {
@ -13,8 +36,29 @@ object MessagesSupplier {
messages = array messages = array
} }
fun checkIfContains(message: Message) { fun checkIfContains(message: Message): Boolean {
for (i in messages.indices) {
messages[i]?.let {
if (message.senderId == it.senderId) {
if (message.content == it.content) {
if (message.timestamp == it.timestamp) {
return true
}
}
}
}
}
return false
}
fun getIndexOfLastMessageFromSelf(): Int? {
var i: Int? = null
for (n in messages.indices) {
if (messages[n]!!.senderId == GeneralVariables.id) {
i = n
}
}
return i
} }
fun wipeData() { fun wipeData() {

@ -1,14 +1,19 @@
package com.example.wikispot package com.example.wikispot
import android.util.DisplayMetrics
import com.example.wikispot.modelClasses.ServerManager import com.example.wikispot.modelClasses.ServerManager
import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.LatLng
import org.json.JSONArray
object GeneralVariables { object GeneralVariables {
var appRunningFirstTime = true var appRunningFirstTime = true
var id: String? = null
var name: String? = null
const val variableMissingKeyword = "_[{(V,a,r,i,a,b,l,e, ,m,i,s,s,i,n,g)}]_"
} }
object IntentsKeys { object IntentsKeys {
@ -22,17 +27,22 @@ object ServerManagement {
var serverManager = ServerManager() var serverManager = ServerManager()
const val receiverConnectionOnCheckWait: Long = 4000 const val receiverConnectionOnCheckWait: Long = 4000
const val viewConnectionOnCheckWait: Long = 5000 const val viewConnectionOnCheckWait: Long = 5000
const val chatConnectionOnCheckWait: Long = 1000
const val dataRequestOnAttemptWait: Long = 2000 const val dataRequestOnAttemptWait: Long = 2000
const val imageRequestOnAttemptWait: Long = 2000 const val imageRequestOnAttemptWait: Long = 2000
var baseUrl = "http://192.168.1.156:8000/" var baseUrl = "http://192.168.1.156:8000/"
var selectedServerId = 0 var selectedServerId = 0
const val sensors_keyword = "_[{(S,e,n,s,o,r,s)}]_" const val sensors_keyword = "_[{(S,e,n,s,o,r,s)}]_"
const val chat_keyword = "_[{(C,h,a,t)}]_"
var totalNumberOfRequestsSent = 0 var totalNumberOfRequestsSent = 0
} }
object ChatManagement {
var lastNames = JSONArray()
const val numberOfNamesToCache = 4
}
object MapManagement { object MapManagement {
var connectedServerPosition: LatLng? = LatLng(0.toDouble(), 0.toDouble()) var connectedServerPosition: LatLng? = LatLng(0.toDouble(), 0.toDouble())
var lastCoordinates = LatLng(0.toDouble(), 0.toDouble()) var lastCoordinates = LatLng(0.toDouble(), 0.toDouble())

@ -9,7 +9,7 @@
/> />
<stroke <stroke
android:color="#7FFFFFFF" android:color="?attr/chatFragmentBgStrokeColor"
android:width="10dp"/> android:width="10dp"/>
</shape> </shape>

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal"
android:autoMirrored="true">
<path
android:fillColor="@android:color/white"
android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z"/>
</vector>

@ -5,6 +5,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:backgroundTint="?attr/exploreFragmentListItemBackgroundColor"
android:layout_margin="5dp" android:layout_margin="5dp"
card_view:cardCornerRadius="10dp"> card_view:cardCornerRadius="10dp">

@ -1,10 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginTop="2dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="2dp"
android:backgroundTint="#22FFFFFF"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="0dp">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -17,11 +23,11 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
android:layout_marginTop="36dp" android:layout_marginTop="36dp"
tools:text="Filename"
android:textSize="24sp" android:textSize="24sp"
android:textStyle="bold" android:textStyle="bold"
card_view:layout_constraintStart_toStartOf="parent" card_view:layout_constraintStart_toStartOf="parent"
card_view:layout_constraintTop_toTopOf="parent" /> card_view:layout_constraintTop_toTopOf="parent"
tools:text="Filename" />
<ImageView <ImageView
android:id="@+id/showFileBtn" android:id="@+id/showFileBtn"

@ -11,12 +11,47 @@
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/chat_messages_recycler_view" android:id="@+id/chat_messages_recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dp"
android:layout_margin="12dp" android:layout_margin="16dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toTopOf="@+id/constraintLayout"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:background="?attr/chatFragmentWriteBarBgColor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent">
<EditText
android:id="@+id/userMessageText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:ems="10"
android:inputType="textPersonName"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/sendMessageBtn"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/sendMessageBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:src="@drawable/ic_baseline_send_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

@ -4,30 +4,29 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#E35050" android:background="#E34B4B"
tools:context=".fragments.debugFragment"> tools:context=".fragments.debugFragment">
<Button <Button
android:id="@+id/goSecondDebugFragmentBtn" android:id="@+id/goSecondDebugFragmentBtn"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="28dp" android:layout_marginTop="16dp"
android:layout_marginEnd="52dp" android:layout_marginEnd="16dp"
android:text="2" android:text="2"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toBottomOf="@+id/debugFragmentTitle" />
<Button <Button
android:id="@+id/getNumberOfSentRequestsBtn" android:id="@+id/getNumberOfSentRequestsBtn"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="24dp" android:layout_marginTop="16dp"
android:text="Get number of sent requests" android:text="Get number of sent requests"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toStartOf="@+id/goSecondDebugFragmentBtn"
app:layout_constraintHorizontal_bias="0.503"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/goSecondDebugFragmentBtn" /> app:layout_constraintTop_toBottomOf="@+id/debugFragmentTitle" />
<ScrollView <ScrollView
android:id="@+id/scrollView3" android:id="@+id/scrollView3"
@ -56,11 +55,11 @@
</ScrollView> </ScrollView>
<Button <Button
android:id="@+id/changeIpBtn" android:id="@+id/changeUrlBtn"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="Change IP" android:text="Change Url"
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/editTextIp" /> app:layout_constraintTop_toBottomOf="@+id/editTextIp" />
@ -97,6 +96,31 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/changeIpBtn" /> app:layout_constraintTop_toBottomOf="@+id/changeUrlBtn" />
<TextView
android:id="@+id/debugFragmentTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Debug fragment"
android:textColor="#FFFFFF"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/closeAppBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Close app"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/restartAppPartiallyBtn" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

@ -34,18 +34,29 @@
android:name="com.example.wikispot.fragments.infoFragment" android:name="com.example.wikispot.fragments.infoFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="8dp" android:layout_marginStart="8dp"
android:layout_marginTop="40dp" android:layout_marginTop="32dp"
android:layout_marginRight="8dp" android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="32dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toTopOf="@+id/chatBtn"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/home_title"> app:layout_constraintTop_toBottomOf="@+id/home_title"
app:layout_constraintVertical_bias="0.0">
</androidx.fragment.app.FragmentContainerView> </androidx.fragment.app.FragmentContainerView>
<ImageView
android:id="@+id/chatBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginBottom="32dp"
android:src="@drawable/ic_baseline_chat_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

@ -21,9 +21,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="64dp" android:layout_marginStart="64dp"
android:layout_marginLeft="64dp"
android:layout_marginTop="88dp" android:layout_marginTop="88dp"
android:text="Dark theme" android:text="@string/dark_theme"
android:background="@drawable/text_background_gradient" android:background="@drawable/text_background_gradient"
android:padding="5dp" android:padding="5dp"
android:textColor="#FFFFFF" android:textColor="#FFFFFF"

@ -5,7 +5,9 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="5dp" android:layout_margin="5dp"
card_view:cardCornerRadius="2dp"> android:backgroundTint="#22FFFFFF"
card_view:cardCornerRadius="6dp"
card_view:cardElevation="0dp">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -19,7 +21,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="2dp" android:layout_margin="2dp"
android:textSize="20sp" android:textSize="12sp"
android:textStyle="bold" android:textStyle="bold"
card_view:layout_constraintEnd_toEndOf="parent" card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintHorizontal_bias="0.5" card_view:layout_constraintHorizontal_bias="0.5"
@ -33,6 +35,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="2dp" android:layout_margin="2dp"
android:textAlignment="textStart" android:textAlignment="textStart"
android:textSize="18sp"
android:textStyle="bold"
card_view:layout_constraintBottom_toBottomOf="parent" card_view:layout_constraintBottom_toBottomOf="parent"
card_view:layout_constraintEnd_toEndOf="parent" card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintHorizontal_bias="0.5" card_view:layout_constraintHorizontal_bias="0.5"

@ -28,7 +28,7 @@
android:label="fragment_home" android:label="fragment_home"
tools:layout="@layout/fragment_home" > tools:layout="@layout/fragment_home" >
<action <action
android:id="@+id/action_homeFragment_to_chatFragment" android:id="@+id/homeFragment_to_chatFragment"
app:destination="@id/chatFragment" /> app:destination="@id/chatFragment" />
<action <action
android:id="@+id/homeFragment_to_mapFragment" android:id="@+id/homeFragment_to_mapFragment"

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">WikiSpot</string>
<string name="chat">Plaudern</string>
<string name="explore">Erkunden</string>
<string name="home">Start</string>
<string name="map">Karte</string>
<string name="settings">Einstellungen</string>
<string name="files">Dateien</string>
<string name="dark_theme">Dunkles Thema</string>
</resources>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ウィキすぽっと</string>
<string name="map">地図</string>
<string name="chat">チャット</string>
<string name="explore">見る</string>
<string name="home"></string>
<string name="files">ファイル</string>
<string name="settings">設定</string>
<string name="dark_theme">暗いテーマ</string>
</resources>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">WikiSpot</string>
<string name="dark_theme">темная тема</string>
<string name="files">файлы</string>
<string name="settings">настройки</string>
<string name="map">карта</string>
<string name="home">дом</string>
<string name="explore">просматривать</string>
<string name="chat">чат</string>
</resources>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">WikiSpot</string>
<string name="chat">Čet</string>
<string name="explore">Prehliadať</string>
<string name="home">Domov</string>
<string name="map">Mapa</string>
<string name="settings">Nastavenia</string>
<string name="files">Súbory</string>
<string name="dark_theme">Tmavá téma</string>
</resources>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- For gradient Backgrounds --> <!-- For Backgrounds -->
<attr name="textBackgroundGradientStartColor" format="color"/> <attr name="textBackgroundGradientStartColor" format="color"/>
<attr name="textBackgroundGradientEndColor" format="color"/> <attr name="textBackgroundGradientEndColor" format="color"/>
@ -12,10 +12,13 @@
<attr name="chatFragmentGradientStartColor" format="color"/> <attr name="chatFragmentGradientStartColor" format="color"/>
<attr name="chatFragmentGradientCenterColor" format="color"/> <attr name="chatFragmentGradientCenterColor" format="color"/>
<attr name="chatFragmentGradientEndColor" format="color"/> <attr name="chatFragmentGradientEndColor" format="color"/>
<attr name="chatFragmentBgStrokeColor" format="color" />
<attr name="chatFragmentWriteBarBgColor" format="color" />
<attr name="exploreFragmentGradientStartColor" format="color"/> <attr name="exploreFragmentGradientStartColor" format="color"/>
<attr name="exploreFragmentGradientCenterColor" format="color"/> <attr name="exploreFragmentGradientCenterColor" format="color"/>
<attr name="exploreFragmentGradientEndColor" format="color"/> <attr name="exploreFragmentGradientEndColor" format="color"/>
<attr name="exploreFragmentListItemBackgroundColor" format="color" />
<attr name="homeFragmentGradientStartColor" format="color"/> <attr name="homeFragmentGradientStartColor" format="color"/>
<attr name="homeFragmentGradientCenterColor" format="color"/> <attr name="homeFragmentGradientCenterColor" format="color"/>

@ -26,10 +26,13 @@
<color name="chatFragmentGradientStartColor" >#FCB0EF</color> <color name="chatFragmentGradientStartColor" >#FCB0EF</color>
<color name="chatFragmentGradientCenterColor" >#9ECFFF</color> <color name="chatFragmentGradientCenterColor" >#9ECFFF</color>
<color name="chatFragmentGradientEndColor" >#9FE7FF</color> <color name="chatFragmentGradientEndColor" >#9FE7FF</color>
<color name="chatFragmentBgStrokeColor" >#7FFFFFFF</color>
<color name="chatFragmentWriteBarBgColor">#FFF</color>
<color name="exploreFragmentGradientStartColor" >#A1DEFC</color> <color name="exploreFragmentGradientStartColor" >#A1DEFC</color>
<color name="exploreFragmentGradientCenterColor" >#A5CBFF</color> <color name="exploreFragmentGradientCenterColor" >#A5CBFF</color>
<color name="exploreFragmentGradientEndColor" >#F9B6F6</color> <color name="exploreFragmentGradientEndColor" >#F9B6F6</color>
<color name="exploreFragmentListItemBackgroundColor">#fff</color>
<color name="homeFragmentGradientStartColor" >#83E1FF</color> <color name="homeFragmentGradientStartColor" >#83E1FF</color>
<color name="homeFragmentGradientCenterColor" >#9EC6FF</color> <color name="homeFragmentGradientCenterColor" >#9EC6FF</color>
@ -55,32 +58,35 @@
<color name="bottomNavBarCheckedItemColorDark">#FFB571</color> <color name="bottomNavBarCheckedItemColorDark">#FFB571</color>
<color name="bottomNavBarItemColorDark">#320747</color> <color name="bottomNavBarItemColorDark">#320747</color>
<color name="bottomNavBarRippleColorDark">#33222222</color> <color name="bottomNavBarRippleColorDark">#33222222</color>
<color name="statusBarColorDark">#4527A0</color> <color name="statusBarColorDark">#000000</color>
<color name="textBackgroundGradientStartColorDark" >#80E5BEFF</color> <color name="textBackgroundGradientStartColorDark" >#80A185B4</color>
<color name="textBackgroundGradientEndColorDark" >#80FFB5F0</color> <color name="textBackgroundGradientEndColorDark" >#80926789</color>
<color name="bottomNavBarGradientStartColorDark" >#FCDD94</color> <color name="bottomNavBarGradientStartColorDark" >#9F8B5D</color>
<color name="bottomNavBarGradientEndColorDark" >#C5F8AB</color> <color name="bottomNavBarGradientEndColorDark" >#749265</color>
<color name="chatFragmentGradientStartColorDark" >#FCB0EF</color> <color name="chatFragmentGradientStartColorDark" >#885E81</color>
<color name="chatFragmentGradientCenterColorDark" >#9ECFFF</color> <color name="chatFragmentGradientCenterColorDark" >#516B85</color>
<color name="chatFragmentGradientEndColorDark" >#9FE7FF</color> <color name="chatFragmentGradientEndColorDark" >#5E8A99</color>
<color name="chatFragmentBgStrokeColorDark" >#D43E3E3E</color>
<color name="chatFragmentWriteBarBgColorDark">#444</color>
<color name="exploreFragmentGradientStartColorDark" >#A1DEFC</color> <color name="exploreFragmentGradientStartColorDark" >#587A8B</color>
<color name="exploreFragmentGradientCenterColorDark" >#A5CBFF</color> <color name="exploreFragmentGradientCenterColorDark" >#657C9C</color>
<color name="exploreFragmentGradientEndColorDark" >#F9B6F6</color> <color name="exploreFragmentGradientEndColorDark" >#896488</color>
<color name="exploreFragmentListItemBackgroundColorDark">#636363</color>
<color name="homeFragmentGradientStartColorDark" >#83E1FF</color> <color name="homeFragmentGradientStartColorDark" >#4F889A</color>
<color name="homeFragmentGradientCenterColorDark" >#9EC6FF</color> <color name="homeFragmentGradientCenterColorDark" >#647EA3</color>
<color name="homeFragmentGradientEndColorDark" >#FEBBFF</color> <color name="homeFragmentGradientEndColorDark" >#977098</color>
<color name="settingsFragmentGradientStartColorDark" >#92EB97FC</color> <color name="settingsFragmentGradientStartColorDark" >#92875691</color>
<color name="settingsFragmentGradientCenterColorDark" >#A198F9</color> <color name="settingsFragmentGradientCenterColorDark" >#6863A2</color>
<color name="settingsFragmentGradientEndColorDark" >#74C7F7</color> <color name="settingsFragmentGradientEndColorDark" >#4B7F9D</color>
<color name="infoFragmentGradientStartColorDark" >#FFB6FB</color> <color name="infoFragmentGradientStartColorDark" >#966B94</color>
<color name="infoFragmentGradientCenterColorDark" >#A7D2FF</color> <color name="infoFragmentGradientCenterColorDark" >#69829D</color>
<color name="infoFragmentGradientEndColorDark" >#96E7FF</color> <color name="infoFragmentGradientEndColorDark" >#54818E</color>
</resources> </resources>

@ -6,7 +6,6 @@
<string name="map">Map</string> <string name="map">Map</string>
<string name="settings">Settings</string> <string name="settings">Settings</string>
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="files">Files</string> <string name="files">Files</string>
<string name="dark_theme">Dark theme</string>
</resources> </resources>

@ -12,7 +12,7 @@
<item name="colorSecondaryVariant">@color/secondaryVariant</item> <item name="colorSecondaryVariant">@color/secondaryVariant</item>
<item name="colorOnSecondary">@color/onSecondary</item> <item name="colorOnSecondary">@color/onSecondary</item>
<!-- For gradient Backgrounds --> <!-- For Backgrounds -->
<item name="textBackgroundGradientStartColor" >@color/textBackgroundGradientStartColor</item> <item name="textBackgroundGradientStartColor" >@color/textBackgroundGradientStartColor</item>
<item name="textBackgroundGradientEndColor" >@color/textBackgroundGradientEndColor</item> <item name="textBackgroundGradientEndColor" >@color/textBackgroundGradientEndColor</item>
@ -23,10 +23,13 @@
<item name="chatFragmentGradientStartColor" >@color/chatFragmentGradientStartColor</item> <item name="chatFragmentGradientStartColor" >@color/chatFragmentGradientStartColor</item>
<item name="chatFragmentGradientCenterColor" >@color/chatFragmentGradientCenterColor</item> <item name="chatFragmentGradientCenterColor" >@color/chatFragmentGradientCenterColor</item>
<item name="chatFragmentGradientEndColor" >@color/chatFragmentGradientEndColor</item> <item name="chatFragmentGradientEndColor" >@color/chatFragmentGradientEndColor</item>
<item name="chatFragmentBgStrokeColor">@color/chatFragmentBgStrokeColor</item>
<item name="chatFragmentWriteBarBgColor">@color/chatFragmentWriteBarBgColor</item>
<item name="exploreFragmentGradientStartColor" >@color/exploreFragmentGradientStartColor</item> <item name="exploreFragmentGradientStartColor" >@color/exploreFragmentGradientStartColor</item>
<item name="exploreFragmentGradientCenterColor" >@color/exploreFragmentGradientCenterColor</item> <item name="exploreFragmentGradientCenterColor" >@color/exploreFragmentGradientCenterColor</item>
<item name="exploreFragmentGradientEndColor" >@color/exploreFragmentGradientEndColor</item> <item name="exploreFragmentGradientEndColor" >@color/exploreFragmentGradientEndColor</item>
<item name="exploreFragmentListItemBackgroundColor">@color/exploreFragmentListItemBackgroundColor</item>
<item name="homeFragmentGradientStartColor" >@color/homeFragmentGradientStartColor</item> <item name="homeFragmentGradientStartColor" >@color/homeFragmentGradientStartColor</item>
<item name="homeFragmentGradientCenterColor" >@color/homeFragmentGradientCenterColor</item> <item name="homeFragmentGradientCenterColor" >@color/homeFragmentGradientCenterColor</item>
@ -70,7 +73,7 @@
<item name="colorSecondaryVariant">@color/secondaryVariantDark</item> <item name="colorSecondaryVariant">@color/secondaryVariantDark</item>
<item name="colorOnSecondary">@color/onSecondaryDark</item> <item name="colorOnSecondary">@color/onSecondaryDark</item>
<!-- For gradient Backgrounds --> <!-- For Backgrounds -->
<item name="textBackgroundGradientStartColor" >@color/textBackgroundGradientStartColorDark</item> <item name="textBackgroundGradientStartColor" >@color/textBackgroundGradientStartColorDark</item>
<item name="textBackgroundGradientEndColor" >@color/textBackgroundGradientEndColorDark</item> <item name="textBackgroundGradientEndColor" >@color/textBackgroundGradientEndColorDark</item>
@ -81,10 +84,13 @@
<item name="chatFragmentGradientStartColor" >@color/chatFragmentGradientStartColorDark</item> <item name="chatFragmentGradientStartColor" >@color/chatFragmentGradientStartColorDark</item>
<item name="chatFragmentGradientCenterColor" >@color/chatFragmentGradientCenterColorDark</item> <item name="chatFragmentGradientCenterColor" >@color/chatFragmentGradientCenterColorDark</item>
<item name="chatFragmentGradientEndColor" >@color/chatFragmentGradientEndColorDark</item> <item name="chatFragmentGradientEndColor" >@color/chatFragmentGradientEndColorDark</item>
<item name="chatFragmentBgStrokeColor">@color/chatFragmentBgStrokeColorDark</item>
<item name="chatFragmentWriteBarBgColor">@color/chatFragmentWriteBarBgColorDark</item>
<item name="exploreFragmentGradientStartColor" >@color/exploreFragmentGradientStartColorDark</item> <item name="exploreFragmentGradientStartColor" >@color/exploreFragmentGradientStartColorDark</item>
<item name="exploreFragmentGradientCenterColor" >@color/exploreFragmentGradientCenterColorDark</item> <item name="exploreFragmentGradientCenterColor" >@color/exploreFragmentGradientCenterColorDark</item>
<item name="exploreFragmentGradientEndColor" >@color/exploreFragmentGradientEndColorDark</item> <item name="exploreFragmentGradientEndColor" >@color/exploreFragmentGradientEndColorDark</item>
<item name="exploreFragmentListItemBackgroundColor">@color/exploreFragmentListItemBackgroundColorDark</item>
<item name="homeFragmentGradientStartColor" >@color/homeFragmentGradientStartColorDark</item> <item name="homeFragmentGradientStartColor" >@color/homeFragmentGradientStartColorDark</item>
<item name="homeFragmentGradientCenterColor" >@color/homeFragmentGradientCenterColorDark</item> <item name="homeFragmentGradientCenterColor" >@color/homeFragmentGradientCenterColorDark</item>