more changes

This commit is contained in:
Tucan444 2021-04-13 09:53:32 +02:00
parent 154a52e30d
commit f3d90ae42a
27 changed files with 871 additions and 396 deletions

@ -1,6 +1,7 @@
<component name="ProjectDictionaryState"> <component name="ProjectDictionaryState">
<dictionary name="ben44"> <dictionary name="ben44">
<words> <words>
<w>backstack</w>
<w>filetype</w> <w>filetype</w>
<w>initing</w> <w>initing</w>
</words> </words>

@ -2,6 +2,7 @@ plugins {
id 'com.android.application' id 'com.android.application'
id 'kotlin-android' id 'kotlin-android'
id 'kotlin-android-extensions' id 'kotlin-android-extensions'
id 'androidx.navigation.safeargs.kotlin'
} }
android { android {
@ -35,7 +36,7 @@ android {
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
kotlinOptions { kotlinOptions {
jvmTarget = '1.8' jvmTarget = JavaVersion.VERSION_1_8.toString()
} }
} }
@ -50,10 +51,13 @@ dependencies {
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.preference:preference:1.1.1'
implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
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.github.bumptech.glide:glide:4.12.0' implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
} }

@ -0,0 +1,24 @@
<resources>
<!--
TODO: 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:
https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=65:0D:80:30:57:9C:7B:EB:35:6F:CC:61:21:5D:C1:2A:73:E1:D8:20%3Bcom.example.wikispot
You can also add your credentials to an existing key, using these values:
Package name:
com.example.wikispot
SHA-1 certificate fingerprint:
65:0D:80:30:57:9C:7B:EB:35:6F:CC:61:21:5D:C1:2A:73:E1:D8:20
Alternatively, follow the directions here:
https://developers.google.com/maps/documentation/android/start#get-key
Once you have your key (it starts with "AIza"), replace the "google_maps_key"
string in this file.
-->
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyAixBio8FevppLsncIkFUQarx2kUB-0dW0</string>
</resources>

@ -3,6 +3,12 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="com.example.wikispot"> package="com.example.wikispot">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the "MyLocation" functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
@ -13,9 +19,23 @@
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:usesCleartextTraffic="true" android:theme="@style/Theme.WikiSpot"
android:theme="@style/Theme.WikiSpot"> android:usesCleartextTraffic="true">
<activity android:name=".activities.MainActivity"
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".activities.MainActivity"
android:screenOrientation="portrait"> android:screenOrientation="portrait">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

@ -1,5 +1,7 @@
package com.example.wikispot package com.example.wikispot
import android.app.Activity
import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.os.Environment import android.os.Environment
import android.view.View import android.view.View
@ -31,38 +33,6 @@ fun Context.getThemeId(): Int {
} }
} }
// for client
fun Context.getDataFromServer(): String {
// requesting data
val url = "${ServerManagement.baseUrl}devices_list"
val request = Request.Builder().url(url).build()
val client = OkHttpClient()
var receivedResponse = ""
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
response.body?.let {
receivedResponse = response.body!!.string()
}
}
override fun onFailure(call: Call, e: IOException) {
println("Request Failed")
println(e)
}
})
Thread.sleep(400)
println("[debug] received string: $receivedResponse")
try {
JSONArray(receivedResponse)
return receivedResponse
} catch (exception: Throwable) {
return "[]"
}
}
// working with files // working with files
fun Context.createFile(filename: String, filetype: String): File { fun Context.createFile(filename: String, filetype: String): File {
@ -114,3 +84,14 @@ fun Context.getStringFromSharedPreferences(accessKey: String, preferencesFilenam
return "" return ""
} }
// Activity extensions
fun Activity.askToQuit() {
val builder = AlertDialog.Builder(this)
builder.setTitle("Confirm")
builder.setMessage("Do you want to quit the application?")
builder.setPositiveButton("Yes") { _, _ -> finish()}
builder.setNegativeButton("No") { _, _ -> }
builder.show()
}

@ -3,35 +3,58 @@ package com.example.wikispot.activities
import android.content.Intent import android.content.Intent
import android.graphics.Bitmap import android.graphics.Bitmap
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AlertDialog import android.util.DisplayMetrics
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import com.example.wikispot.IntentsKeys import androidx.recyclerview.widget.LinearLayoutManager
import com.example.wikispot.R import com.example.wikispot.*
import com.example.wikispot.ServerManagement import com.example.wikispot.adapters.LabeledValuesAdapter
import com.example.wikispot.fragments.* import com.example.wikispot.fragments.*
import com.example.wikispot.getThemeId
import com.example.wikispot.modelClasses.JsonManager import com.example.wikispot.modelClasses.JsonManager
import com.example.wikispot.modelClasses.JsonManagerLite import com.example.wikispot.modelClasses.JsonManagerLite
import com.example.wikispot.modelClasses.SettingsSaveManager import com.example.wikispot.modelClasses.SettingsSaveManager
import com.example.wikispot.modelsForAdapters.LabeledValue
import com.example.wikispot.modelsForAdapters.LabeledValuesSupplier
import com.example.wikispot.modelsForAdapters.PlacePreview import com.example.wikispot.modelsForAdapters.PlacePreview
import com.example.wikispot.modelsForAdapters.PlaceSupplier import com.example.wikispot.modelsForAdapters.PlaceSupplier
import com.google.android.gms.maps.model.LatLng
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_info.*
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
override fun onBackPressed() { override fun onBackPressed() {
val builder = AlertDialog.Builder(this)
builder.setTitle("Confirm") try {
builder.setMessage("Do you want to quit the application?") when (val currentlyShownFragment = mainFragmentHost.childFragmentManager.fragments[0]) {
builder.setPositiveButton("Yes") { _, _ -> finish()} is chatFragment -> {
builder.setNegativeButton("No") { _, _ -> } askToQuit()
builder.show() }
is exploreFragment -> {
askToQuit()
}
is homeFragment -> {
askToQuit()
}
is mapFragment -> {
askToQuit()
}
is settingsFragment -> {
askToQuit()
}
is infoFragment -> {
currentlyShownFragment.goExploreFragment()
}
}
} catch (e: Throwable) { println(e) }
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
doPreparations()
loadSettings() loadSettings()
setTheme(getThemeId()) setTheme(getThemeId())
@ -44,43 +67,108 @@ class MainActivity : AppCompatActivity() {
handleExtras() handleExtras()
} }
private fun doPreparations() {
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
ScreenParameters.height = displayMetrics.heightPixels
ScreenParameters.width = displayMetrics.widthPixels
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
// server communication // server communication
val dataReceiver: (String) -> Unit = {data: String -> val dataReceiver0: (String) -> Unit = { data0: String ->
println("Data here: $data") val dataReceiver1: (String) -> Unit = { data1: String ->
val json = JsonManager(this, data1, "JSONObject")
val names = json.currentJsonObject!!.names()
println("[debug] $data1")
try { try {
when (mainFragmentHost.childFragmentManager.fragments[0]) { mainFragmentHost.childFragmentManager.fragments[0]?.let {
is chatFragment -> {} when (it) {
is exploreFragment -> {} is chatFragment -> {
is homeFragment -> {} }
is mapFragment -> {} is exploreFragment -> {
is settingsFragment -> {} }
is homeFragment -> {
LabeledValuesSupplier.wipeData()
for (n in 0 until names!!.length()) {
val labeledValue = LabeledValue(names[n].toString(), json.getAttributeContent(names[n].toString()))
if (!LabeledValuesSupplier.checkIfContains(labeledValue)) {
LabeledValuesSupplier.appendLabeledValue(labeledValue)
}
}
it.labeled_values_recycler_view.post {
val layoutManager = LinearLayoutManager(it.requireContext())
layoutManager.orientation = LinearLayoutManager.VERTICAL
it.labeled_values_recycler_view.layoutManager = layoutManager
val adapter = LabeledValuesAdapter(it.requireContext(), LabeledValuesSupplier.labeledValues)
it.labeled_values_recycler_view.adapter = adapter
}
}
is mapFragment -> {
}
is settingsFragment -> {
}
is infoFragment -> {
}
else -> println("[debug] unknown fragment in sensorsConnection")
}
} }
} catch (e: Throwable) { println(e) } } catch (e: Throwable) { println(e) }
} }
println(data0)
ServerManagement.serverManager.addReceiverConnection(dataReceiver, this, "mainConnection", 0, "test0.json") if (!ServerManagement.serverManager.checkIfConnectionAlreadyExists("sensorsConnection")){
ServerManagement.serverManager.addReceiverConnection(dataReceiver1, this, "sensorsConnection", data0.toInt(), ServerManagement.sensors_keyword)
}
// getting other needed information
val dataReceiver2: (String) -> Unit = {data1: String ->
var json = JsonManager(this, data1)
json = JsonManager(this, json.findJsonObjectByAttribute("ID", data0.toInt()), "JSONObject")
val positionsList = json.getAttributeContent("location").split(",")
MapManagement.connectedServerTitle = json.getAttributeContentByPath("description/title")
MapManagement.connectedServerPosition = LatLng(positionsList[0].toDouble(), positionsList[1].toDouble())
}
if (!ServerManagement.serverManager.checkIfConnectionAlreadyExists("mapConnection")){
ServerManagement.serverManager.addReceiverConnection(dataReceiver2, this, "mapConnection", data0.toInt(), "", "GET_WHOLE_ARRAY")
}
}
ServerManagement.serverManager.getData(dataReceiver0, this, 0, "", "connected_id", 3)
connectExploreFragmentAdapterModel() connectExploreFragmentAdapterModel()
} }
override fun onPause() { override fun onPause() {
PlaceSupplier.saveToCache(this) PlaceSupplier.saveToCache(this)
ServerManagement.serverManager.deleteConnection("mainConnection") ServerManagement.serverManager.deleteConnection("sensorsConnection")
ServerManagement.serverManager.deleteConnection("mapConnection")
ServerManagement.serverManager.deleteConnection("exploreListConnection") ServerManagement.serverManager.deleteConnection("exploreListConnection")
super.onPause() super.onPause()
} }
private fun handleExtras() { private fun handleExtras() {
when (intent.getStringExtra(IntentsKeys.startFragment)) { when (intent.getStringExtra(IntentsKeys.startFragment)) {
"chatFragment" -> {mainBottomNavigationView.selectedItemId = R.id.chatFragment} "chatFragment" -> {
"exploreFragment" -> {mainBottomNavigationView.selectedItemId = R.id.exploreFragment} mainBottomNavigationView.selectedItemId = R.id.chatFragment
}
"exploreFragment" -> {
mainBottomNavigationView.selectedItemId = R.id.exploreFragment
}
// skipping home fragment because were already here // skipping home fragment because were already here
"mapFragment" -> {mainBottomNavigationView.selectedItemId = R.id.mapFragment} "mapFragment" -> {
"settingsFragment" -> {mainBottomNavigationView.selectedItemId = R.id.settingsFragment} mainBottomNavigationView.selectedItemId = R.id.mapFragment
}
"settingsFragment" -> {
mainBottomNavigationView.selectedItemId = R.id.settingsFragment
}
} }
} }
@ -102,14 +190,15 @@ class MainActivity : AppCompatActivity() {
PlaceSupplier.controlJson = JsonManagerLite(data) PlaceSupplier.controlJson = JsonManagerLite(data)
} }
for (i in 1 until json.getLengthOfJsonArray()) { // todo change to 1 for (i in 1 until json.getLengthOfJsonArray()) {
json.getJsonObject(i) json.getJsonObject(i)
val id = json.getAttributeContent("ID").toInt() val id = json.getAttributeContent("ID").toInt()
val location = json.getAttributeContent("location")
json.getAttributeContent("description") json.getAttributeContent("description")
val title = json.getAttributeContent("title") val title = json.getAttributeContent("title")
val shortDescription = json.getAttributeContent("description_s") val shortDescription = json.getAttributeContent("description_s")
val place = PlacePreview(title, shortDescription, null, id) val place = PlacePreview(title, shortDescription, location, null, id)
if (!PlaceSupplier.checkIfContains(place)) { if (!PlaceSupplier.checkIfContains(place)) {
@ -145,11 +234,21 @@ class MainActivity : AppCompatActivity() {
try { try {
when (mainFragmentHost.childFragmentManager.fragments[0]) { when (mainFragmentHost.childFragmentManager.fragments[0]) {
is chatFragment -> {currentNavHostFragmentName = "chatFragment"} is chatFragment -> {
is exploreFragment -> {currentNavHostFragmentName= "exploreFragment"} currentNavHostFragmentName = "chatFragment"
is homeFragment -> {currentNavHostFragmentName = "homeFragment"} }
is mapFragment -> {currentNavHostFragmentName = "mapFragment"} is exploreFragment -> {
is settingsFragment -> {currentNavHostFragmentName = "settingsFragment"} currentNavHostFragmentName = "exploreFragment"
}
is homeFragment -> {
currentNavHostFragmentName = "homeFragment"
}
is mapFragment -> {
currentNavHostFragmentName = "mapFragment"
}
is settingsFragment -> {
currentNavHostFragmentName = "settingsFragment"
}
} }
} catch (e: Throwable) { println(e) } } catch (e: Throwable) { println(e) }

@ -8,8 +8,10 @@ import androidx.navigation.Navigation
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.example.wikispot.R import com.example.wikispot.R
import com.example.wikispot.ServerManagement import com.example.wikispot.ServerManagement
import com.example.wikispot.fragments.exploreFragmentDirections
import com.example.wikispot.modelsForAdapters.PlacePreview import com.example.wikispot.modelsForAdapters.PlacePreview
import com.example.wikispot.showToast import com.example.wikispot.showToast
import com.google.android.gms.maps.model.LatLng
import kotlinx.android.synthetic.main.explore_list_item.view.* import kotlinx.android.synthetic.main.explore_list_item.view.*
@ -19,11 +21,20 @@ class PlacePreviewsAdapter(private val context: Context, private val placePrevie
var currentPlacePreview: PlacePreview? = null var currentPlacePreview: PlacePreview? = null
var pos: Int = 0 var pos: Int = 0
var location: LatLng? = null
init { init {
itemView.setOnClickListener { itemView.setOnClickListener {
ServerManagement.selectedServerId = currentPlacePreview?.id!! ServerManagement.selectedServerId = currentPlacePreview?.id!!
Navigation.findNavController(it).navigate(R.id.navigateToInfoFragment) val action = exploreFragmentDirections.navigateToInfoFragment(true)
Navigation.findNavController(it).navigate(action)
}
itemView.item_location_img.setOnClickListener {
if (location != null) {
val action = exploreFragmentDirections.navigateToMapFragment(location!!, currentPlacePreview!!.title)
Navigation.findNavController(it).navigate(action)
}
} }
} }
@ -31,6 +42,14 @@ class PlacePreviewsAdapter(private val context: Context, private val placePrevie
placePreview?.let { placePreview?.let {
itemView.item_title.text = placePreview.title itemView.item_title.text = placePreview.title
itemView.item_description.text = placePreview.description itemView.item_description.text = placePreview.description
try {
val coordinates = placePreview.location!!.split(",")
location = LatLng(coordinates[0].toDouble(), coordinates[1].toDouble())
} catch (e: Throwable) {
println("[debug] Failed getting coordinates in ${placePreview.title}, explore fragment list. Exception: $e")}
placePreview.img?.let { placePreview.img?.let {
itemView.item_img.setImageBitmap(placePreview.img) itemView.item_img.setImageBitmap(placePreview.img)
} }

@ -0,0 +1,44 @@
package com.example.wikispot.adapters
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.wikispot.R
import com.example.wikispot.modelsForAdapters.LabeledValue
import kotlinx.android.synthetic.main.labeled_value_item.view.*
class LabeledValuesAdapter(private val context: Context, private val labeledValues: Array<LabeledValue?>) : RecyclerView.Adapter<LabeledValuesAdapter.MyViewHolder>() {
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var currentLabeledValue: LabeledValue? = null
var pos: Int = 0
fun setData(labeledValue: LabeledValue?, pos: Int) {
labeledValue?.let {
itemView.label.text = labeledValue.label
itemView.value.text = labeledValue.value
}
this.currentLabeledValue = labeledValue
this.pos = pos
}
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val labeledValue = labeledValues[position]
holder.setData(labeledValue, position)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.labeled_value_item, parent, false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
return labeledValues.size
}
}

@ -1,12 +1,15 @@
package com.example.wikispot.fragments package com.example.wikispot.fragments
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
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 androidx.navigation.Navigation
import com.example.wikispot.R import com.example.wikispot.R
import com.example.wikispot.getDataFromServer import com.example.wikispot.ServerManagement
import com.example.wikispot.modelClasses.JsonManager import com.example.wikispot.modelClasses.JsonManager
import kotlinx.android.synthetic.main.fragment_debug.* import kotlinx.android.synthetic.main.fragment_debug.*
@ -19,39 +22,41 @@ class debugFragment : Fragment(R.layout.fragment_debug) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
getDataBtn.setOnClickListener {
context?.let {
jsonManager = JsonManager(requireContext(), requireContext().getDataFromServer(), "JSONArray", true)
sizeView.text = jsonManager.getLengthOfJsonArray().toString()
}
}
getJsonFileBtn.setOnClickListener {
val id = idInput.text.toString().toInt()
jsonFileContentView.text = jsonManager.getJsonObject(id).toString()
}
getAttributeContentBtn.setOnClickListener {
val attributeName = attributeNameInput.text.toString()
if ("/" in attributeName) {
attributeContentView.text = jsonManager.getAttributeContentByPath(attributeNameInput.text.toString())
} else {
attributeContentView.text = jsonManager.getAttributeContent(attributeNameInput.text.toString())
}
}
clearAttributeBtn.setOnClickListener {
jsonManager.clearSelectedAttribute()
attributeContentView.text = "attribute content"
}
attributeNameInput.setOnClickListener {
attributeContentView.text = jsonManager.getCurrentJsonAttributeContent()
}
// handling navigation between debug fragments
goSecondDebugFragmentBtn.setOnClickListener { goSecondDebugFragmentBtn.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.navigateToAnotherDebugFragment) Navigation.findNavController(it).navigate(R.id.navigateToAnotherDebugFragment)
} }
getNumberOfSentRequestsBtn.setOnClickListener {
outputText.text = ServerManagement.totalNumberOfRequestsSent.toString()
}
val pdfRequestThread = Thread(PdfRequest())
pdfRequestThread.start()
}
inner class PdfRequest : Runnable {
override fun run() {
val inputStream = java.net.URL("${ServerManagement.baseUrl}files/1/sample.pdf").openStream()
val uri = Uri.parse("${ServerManagement.baseUrl}files/1/sample.pdf")
Thread.sleep(500)
pdfView.post {
println("asdfsdfsdfs")
//pdfView.fromUri(uri).load()
pdfView.fromStream(inputStream).pages(0).load()
pdfView.zoomTo(pdfView.width / 490.0F)
println("[debug] zoom is ${pdfView.width / 490.0F}")
println(pdfView.width)
Thread.sleep(1000)
println(pdfView.currentPage)
}
ServerManagement.totalNumberOfRequestsSent += 1
}
} }
} }

@ -1,5 +1,6 @@
package com.example.wikispot.fragments package com.example.wikispot.fragments
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
@ -39,11 +40,20 @@ class homeFragment : Fragment(R.layout.fragment_home) {
fragment.mainDescription.text = json.getAttributeContentByPath("description/description_l") fragment.mainDescription.text = json.getAttributeContentByPath("description/description_l")
} }
} }
val imageReceiver: (Bitmap) -> Unit = { bitmap: Bitmap ->
homeFragmentInnerFragment.post {
homeFragmentInnerFragment.mainImage.setImageBitmap(bitmap)
}
}
ServerManagement.serverManager.getImage(imageReceiver, json.getAttributeContent("ID").toInt(), "test0.jpg", 3)
} }
} catch (e: Throwable) { println(e) } } catch (e: Throwable) { println(e) }
} }
ServerManagement.serverManager.getData(dataReceiver, requireContext(), 0, "", "GET_JSON_ARRAY", 3) ServerManagement.serverManager.getData(dataReceiver, requireContext(), 0, "", "GET_WHOLE_ARRAY", 3)
} }

@ -1,19 +1,134 @@
package com.example.wikispot.fragments package com.example.wikispot.fragments
import android.graphics.Bitmap
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.wikispot.R import com.example.wikispot.R
import com.example.wikispot.ServerManagement
import com.example.wikispot.adapters.LabeledValuesAdapter
import com.example.wikispot.modelClasses.JsonManager import com.example.wikispot.modelClasses.JsonManager
import com.example.wikispot.modelsForAdapters.LabeledValue
import com.example.wikispot.modelsForAdapters.LabeledValuesSupplier
import com.google.android.gms.maps.model.LatLng
import kotlinx.android.synthetic.main.fragment_info.* import kotlinx.android.synthetic.main.fragment_info.*
class infoFragment() : Fragment(R.layout.fragment_info) { class infoFragment() : Fragment(R.layout.fragment_info) {
private val args: infoFragmentArgs by navArgs()
var location: LatLng? = null
var loadAutomatically = false
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
updateRecyclerView()
try {
loadAutomatically = args.loadAutomatically
} catch (e: Throwable) { println("[debug] Exception in Info Fragment while getting args: $e") }
if (loadAutomatically) {
load()
}
locationBtn.setOnClickListener {
if (loadAutomatically) {
if (location != null) {
val action = infoFragmentDirections.infoFragmentToMapFragment(location!!, mainTitle.text.toString())
Navigation.findNavController(it).navigate(action)
}
} else {
Navigation.findNavController(it).navigate(R.id.homeFragment_to_mapFragment)
}
}
}
private fun load() {
val serverId = ServerManagement.selectedServerId
val dataReceiver: (String) -> Unit = { data: String ->
try {
context?.let {
val json = JsonManager(requireContext(), data)
json.findJsonObjectByAttribute("ID", serverId)
mainTitle.post {
mainTitle.text = json.getAttributeContentByPath("description/title")
}
mainDescription.post {
this.mainDescription.text = json.getAttributeContentByPath("description/description_s")
}
val imageReceiver: (Bitmap) -> Unit = { bitmap: Bitmap ->
mainImage.post {
mainImage?.let {
mainImage.setImageBitmap(bitmap)
}
}
}
val coordinates = json.getAttributeContent("location").split(",")
location = LatLng(coordinates[0].toDouble(), coordinates[1].toDouble())
ServerManagement.serverManager.getImage(imageReceiver, json.getAttributeContent("ID").toInt(), "test0.jpg", 2)
}
} catch (e: Throwable) { println(e) }
}
val sensorsDataReceiver: (String) -> Unit = {data: String ->
try {
context?.let {
println("[debug][info fragment] $data")
val json = JsonManager(requireContext(), data, "JSONObject")
val names = json.currentJsonObject!!.names()
LabeledValuesSupplier.wipeData()
for (n in 0 until names!!.length()) {
val labeledValue = LabeledValue(names[n].toString(), json.getAttributeContent(names[n].toString()))
if (!LabeledValuesSupplier.checkIfContains(labeledValue)) {
LabeledValuesSupplier.appendLabeledValue(labeledValue)
}
}
updateRecyclerView()
}
} catch (e: Throwable) { println(e) }
}
context?.let {
ServerManagement.serverManager.getData(dataReceiver, requireContext(), serverId, "", "GET_WHOLE_ARRAY")
ServerManagement.serverManager.addReceiverConnection(sensorsDataReceiver, requireContext(), "infoFragmentSensorsConnection",
serverId, ServerManagement.sensors_keyword)
}
}
override fun onPause() {
ServerManagement.serverManager.deleteConnection("infoFragmentSensorsConnection")
super.onPause()
}
private fun updateRecyclerView() {
labeled_values_recycler_view.post {
val layoutManager = LinearLayoutManager(context)
layoutManager.orientation = LinearLayoutManager.VERTICAL
labeled_values_recycler_view.layoutManager = layoutManager
val adapter = context?.let { LabeledValuesAdapter(it, LabeledValuesSupplier.labeledValues) }
labeled_values_recycler_view.adapter = adapter
}
}
fun goExploreFragment() {
Navigation.findNavController(mainTitle).navigate(R.id.navigateBackToExploreFragment)
} }
} }

@ -1,12 +1,63 @@
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.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs
import com.example.wikispot.MapManagement
import com.example.wikispot.R import com.example.wikispot.R
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
class mapFragment : Fragment() {
class mapFragment : Fragment(R.layout.fragment_map) { val args: mapFragmentArgs by navArgs()
private var loadFromMapManager = true
var location: LatLng? = null
var markerTitle: String? = null
private val callback = OnMapReadyCallback { googleMap ->
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera.
* In this case, we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to
* install it inside the SupportMapFragment. This method will only be triggered once the
* user has installed Google Play services and returned to the app.
*/
/*val pb = LatLng(49.11274928646463, 18.443442353021045)
googleMap.addMarker(MarkerOptions().position(pb).title("Povazska Bystrica"))
googleMap.moveCamera(CameraUpdateFactory.newLatLng(pb))
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(pb, 16.0f)) */
try {
location = args.location
markerTitle = args.markerTitle
loadFromMapManager = false
} catch (e: Throwable) { println("[debug] Exception in Map Fragment while getting args: $e") }
if (loadFromMapManager) {
googleMap.addMarker(MarkerOptions().position(MapManagement.connectedServerPosition!!).title(MapManagement.connectedServerTitle))
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(MapManagement.connectedServerPosition, 16.0F))
} else {
googleMap.addMarker(MarkerOptions().position(location!!).title(markerTitle))
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(location, 16.0F))
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_map, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
mapFragment?.getMapAsync(callback)
}
} }

@ -16,6 +16,8 @@ class ServerManager {
private var receiverConnections = mutableListOf<ReceiverConnection>() private var receiverConnections = mutableListOf<ReceiverConnection>()
private var viewConnections = mutableListOf<ViewConnection>() private var viewConnections = mutableListOf<ViewConnection>()
// 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()
@ -27,8 +29,12 @@ class ServerManager {
var url = "${ServerManagement.baseUrl}devices_list" var url = "${ServerManagement.baseUrl}devices_list"
if (path != "") { if (path != "") {
if (path.contains(ServerManagement.sensors_keyword)){
url = "${ServerManagement.baseUrl}$serverId/sensors"
} else {
url = "${ServerManagement.baseUrl}files/$serverId/$path" url = "${ServerManagement.baseUrl}files/$serverId/$path"
} }
}
val request = Request.Builder().url(url).build() val request = Request.Builder().url(url).build()
val client = OkHttpClient() val client = OkHttpClient()
@ -46,11 +52,11 @@ class ServerManager {
val jsonManager = JsonManager(context, receivedString) val jsonManager = JsonManager(context, receivedString)
if (path == "") { if (path == "") {
if (attributePath == "GET_JSON_ARRAY") { if (attributePath == "GET_WHOLE_ARRAY") {
dataReceiver(jsonManager.jsonArray.toString()) dataReceiver(jsonManager.jsonArray.toString())
return return
} }
jsonManager.getJsonObject(serverId) jsonManager.getJsonObject(0)
} else { } else {
if (attributePath == "") { if (attributePath == "") {
throw Throwable() throw Throwable()
@ -88,6 +94,8 @@ class ServerManager {
} }
}) })
ServerManagement.totalNumberOfRequestsSent += 1
Thread.sleep(ServerManagement.dataRequestOnAttemptWait) Thread.sleep(ServerManagement.dataRequestOnAttemptWait)
} }
} }
@ -110,6 +118,8 @@ class ServerManager {
imageReceiver(bitmap) imageReceiver(bitmap)
} catch (e: Throwable) { println(e) } } catch (e: Throwable) { println(e) }
ServerManagement.totalNumberOfRequestsSent += 1
Thread.sleep(ServerManagement.imageRequestOnAttemptWait) Thread.sleep(ServerManagement.imageRequestOnAttemptWait)
} }
} }
@ -132,8 +142,27 @@ class ServerManager {
} }
} }
fun checkIfConnectionAlreadyExists(connectionName: String, connectionType: String="any"): Boolean{
if ((connectionType == "any") or (connectionType == "receiver")) {
for (n in 0 until receiverConnections.size) {
if (receiverConnections[n].connectionName == connectionName) {
return true
}
}
}
if ((connectionType == "any") or (connectionType == "view")) {
for (n in 0 until viewConnections.size) {
if (viewConnections[n].connectionName == connectionName) {
return true
}
}
}
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 == "activity")) { 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 {
if (receiverConnections[i].connectionName == connectionName) { if (receiverConnections[i].connectionName == connectionName) {
@ -156,11 +185,11 @@ class ServerManager {
} }
} }
fun addReceiverConnection(dataReceiver: (String) -> Unit, context: Context, connectionName: String, serverId: Int, path: String?=null, 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?=null, 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
@ -175,8 +204,12 @@ class ServerManager {
var url = "${ServerManagement.baseUrl}devices_list" var url = "${ServerManagement.baseUrl}devices_list"
if (path != "") { if (path != "") {
if (path.contains(ServerManagement.sensors_keyword)){
url = "${ServerManagement.baseUrl}$serverId/sensors"
} else {
url = "${ServerManagement.baseUrl}files/$serverId/$path" url = "${ServerManagement.baseUrl}files/$serverId/$path"
} }
}
val request = Request.Builder().url(url).build() val request = Request.Builder().url(url).build()
val client = OkHttpClient() val client = OkHttpClient()
@ -198,7 +231,7 @@ class ServerManager {
dataReceiver(jsonManager.jsonArray.toString()) dataReceiver(jsonManager.jsonArray.toString())
return return
} }
jsonManager.getJsonObject(serverId) jsonManager.getJsonObject(0)
} else { } else {
if (attributePath == "") { if (attributePath == "") {
throw Throwable() throw Throwable()
@ -236,6 +269,8 @@ class ServerManager {
} }
}) })
ServerManagement.totalNumberOfRequestsSent += 1
Thread.sleep(waitTime) Thread.sleep(waitTime)
} }
} }
@ -262,8 +297,12 @@ class ServerManager {
var url = "${ServerManagement.baseUrl}devices_list" var url = "${ServerManagement.baseUrl}devices_list"
if (path != "") { if (path != "") {
if (path.contains(ServerManagement.sensors_keyword)){
url = "${ServerManagement.baseUrl}$serverId/sensors"
} else {
url = "${ServerManagement.baseUrl}files/$serverId/$path" url = "${ServerManagement.baseUrl}files/$serverId/$path"
} }
}
val request = Request.Builder().url(url).build() val request = Request.Builder().url(url).build()
val client = OkHttpClient() val client = OkHttpClient()
@ -286,7 +325,7 @@ class ServerManager {
view.text = jsonManager.jsonArray.toString() view.text = jsonManager.jsonArray.toString()
return return
} }
jsonManager.getJsonObject(serverId) jsonManager.getJsonObject(0)
} else { } else {
if (attributePath == "") { if (attributePath == "") {
throw Throwable() throw Throwable()
@ -333,6 +372,9 @@ class ServerManager {
println(e) println(e)
} }
}) })
ServerManagement.totalNumberOfRequestsSent += 1
Thread.sleep(ServerManagement.viewConnectionOnCheckWait) Thread.sleep(ServerManagement.viewConnectionOnCheckWait)
} }
} }

@ -3,13 +3,15 @@ package com.example.wikispot.modelsForAdapters
import android.content.Context import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.media.Image import android.media.Image
import com.example.wikispot.ScreenParameters
import com.example.wikispot.getStringFromSharedPreferences import com.example.wikispot.getStringFromSharedPreferences
import com.example.wikispot.modelClasses.JsonManager import com.example.wikispot.modelClasses.JsonManager
import com.example.wikispot.modelClasses.JsonManagerLite import com.example.wikispot.modelClasses.JsonManagerLite
import com.example.wikispot.saveString import com.example.wikispot.saveString
import com.google.android.gms.maps.model.LatLng
import org.json.JSONArray import org.json.JSONArray
data class PlacePreview(var title: String, var description: String, var img: Bitmap? = null, val id: Int?=null) { data class PlacePreview(var title: String, var description: String, val location: String? = null, var img: Bitmap? = null, val id: Int?=null) {
init { init {
val words = description.split(" ") val words = description.split(" ")
@ -80,7 +82,7 @@ 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("|||||")
val place = PlacePreview(savedData[0], savedData[1], null, savedData[2].toInt()) val place = PlacePreview(savedData[0], savedData[1], savedData[2], null, savedData[3].toInt())
if (!checkIfContains(place)) { if (!checkIfContains(place)) {
appendPlace(place) appendPlace(place)
} }
@ -93,10 +95,9 @@ object PlaceSupplier {
for (n in places.indices) { for (n in places.indices) {
val place = places[n] val place = places[n]
if (getSavePermission(place)) { if (getSavePermission(place)) {
save.put(n, "${place!!.title}|||||${place.description}|||||${place.id}") save.put(n, "${place!!.title}|||||${place.description}|||||${place.location}|||||${place.id}")
} }
} }
//save.put("hi|||||sdhsiujdghsiuy|||||45")
context.saveString("placePreviews", save.toString(), "exploreFragmentCache") context.saveString("placePreviews", save.toString(), "exploreFragmentCache")
} }
@ -111,14 +112,17 @@ object PlaceSupplier {
controlJson!!.getJsonObject(n) controlJson!!.getJsonObject(n)
if (place.id == controlJson!!.getAttributeContent("ID").toInt()) { if (place.id == controlJson!!.getAttributeContent("ID").toInt()) {
if (place.title == controlJson!!.getAttributeContentByPath("description/title")) { if (place.title == controlJson!!.getAttributeContentByPath("description/title")) {
val tempPlace = PlacePreview("", controlJson!!.getAttributeContentByPath("description/description_s")) val tempPlace = PlacePreview("", controlJson!!.getAttributeContentByPath("description/description_s"),
controlJson!!.getAttributeContentByPath("location"))
if (place.description == tempPlace.description) { if (place.description == tempPlace.description) {
if (place.location == tempPlace.location) {
return true return true
} }
} }
} }
} }
} }
}
return false return false
} }

@ -0,0 +1,30 @@
package com.example.wikispot.modelsForAdapters
data class LabeledValue(val label: String, val value: String)
object LabeledValuesSupplier {
var labeledValues = arrayOf<LabeledValue?>()
fun appendLabeledValue(labeledValue: LabeledValue) {
val array = labeledValues.copyOf(labeledValues.size + 1)
array[labeledValues.size] = labeledValue
labeledValues = array
}
fun checkIfContains(labeledValue: LabeledValue): Boolean{
for (n in labeledValues.indices) {
if (labeledValues[n]!!.label == labeledValue.label) {
return true
}
}
return false
}
fun wipeData() {
labeledValues = arrayOf<LabeledValue?>()
}
}

@ -1,6 +1,8 @@
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
object GeneralVariables { object GeneralVariables {
@ -24,6 +26,21 @@ object ServerManagement {
const val imageRequestOnAttemptWait: Long = 2000 const val imageRequestOnAttemptWait: Long = 2000
const val baseUrl = "http://192.168.1.230:8000/" const val baseUrl = "http://192.168.1.230:8000/"
var selectedServerId = 0 var selectedServerId = 0
const val sensors_keyword = "_[{(S,e,n,s,o,r,s)}]_"
var totalNumberOfRequestsSent = 0
}
object MapManagement {
var connectedServerPosition: LatLng? = null
var connectedServerTitle: String? = null
}
object ScreenParameters {
var height = 1
var width = 1
} }

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#C4FFA5"
android:centerColor="#D1FBA0"
android:endColor="#F6FEBA"/>
</shape>

@ -4,163 +4,65 @@
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="#EF5350" android:background="#E35050"
tools:context=".fragments.debugFragment"> tools:context=".fragments.debugFragment">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Debug Fragment"
android:textColor="@android:color/white"
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/getDataBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Get Data"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" />
<EditText
android:id="@+id/idInput"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:ems="10"
android:hint=" id"
android:inputType="number"
app:layout_constraintStart_toStartOf="@+id/getDataBtn"
app:layout_constraintTop_toBottomOf="@+id/getDataBtn" />
<Button
android:id="@+id/getJsonFileBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Json File"
app:layout_constraintStart_toStartOf="@+id/idInput"
app:layout_constraintTop_toBottomOf="@+id/idInput" />
<ScrollView
android:id="@+id/scrollView3"
android:layout_width="380dp"
android:layout_height="100dp"
android:layout_marginTop="16dp"
android:background="#FF6C6C"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/getJsonFileBtn">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/jsonFileContentView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="json content"
android:textAlignment="center"
android:textSize="18sp"
tools:layout_editor_absoluteX="254dp"
tools:layout_editor_absoluteY="95dp" />
</LinearLayout>
</ScrollView>
<TextView
android:id="@+id/sizeView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:text="Amount of json's: 0"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@+id/getJsonFileBtn"
app:layout_constraintStart_toEndOf="@+id/idInput"
app:layout_constraintTop_toBottomOf="@+id/getDataBtn" />
<Button
android:id="@+id/getAttributeContentBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Get Attribute "
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/scrollView3" />
<EditText
android:id="@+id/attributeNameInput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:ems="10"
android:hint=" attribute name"
android:inputType="textPersonName"
app:layout_constraintStart_toStartOf="@+id/getAttributeContentBtn"
app:layout_constraintTop_toBottomOf="@+id/getAttributeContentBtn" />
<ScrollView
android:layout_width="380dp"
android:layout_height="80dp"
android:layout_marginTop="16dp"
android:background="#FF6C6C"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/attributeNameInput">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/attributeContentView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="attribute content"
android:textAlignment="center"
android:textSize="18sp"
android:gravity="center_horizontal" />
</LinearLayout>
</ScrollView>
<Button
android:id="@+id/clearAttributeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginLeft="6dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="Clear Attribute"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/getAttributeContentBtn"
app:layout_constraintTop_toBottomOf="@+id/scrollView3" />
<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="16dp" android:layout_marginTop="28dp"
android:layout_marginEnd="32dp" android:layout_marginEnd="52dp"
android:layout_marginRight="32dp"
android:text="2" android:text="2"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" /> app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/getNumberOfSentRequestsBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Get number of sent requests"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.503"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/goSecondDebugFragmentBtn" />
<ScrollView
android:id="@+id/scrollView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
app:layout_constraintEnd_toEndOf="@+id/getNumberOfSentRequestsBtn"
app:layout_constraintStart_toStartOf="@+id/getNumberOfSentRequestsBtn"
app:layout_constraintTop_toBottomOf="@+id/getNumberOfSentRequestsBtn">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/outputText"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#6A5252"
android:backgroundTint="#E39595"
android:padding="4dp"
android:text="output" />
</LinearLayout>
</ScrollView>
<com.github.barteksc.pdfviewer.PDFView
android:id="@+id/pdfView"
android:layout_width="200dp"
android:layout_height="300dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/scrollView3"
app:layout_constraintVertical_bias="0.17000002" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

@ -1,12 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView 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"
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="@drawable/home_fragment_gradient_background" android:background="@drawable/home_fragment_gradient_background"
tools:background="@drawable/home_fragment_gradient_background" tools:background="@drawable/home_fragment_gradient_background"
tools:context=".fragments.homeFragment"> tools:context=".fragments.homeFragment"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView <TextView
android:id="@+id/textView4" android:id="@+id/textView4"
@ -25,12 +30,11 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView
android:name="com.example.wikispot.fragments.infoFragment"
android:id="@+id/homeFragmentInnerFragment" android:id="@+id/homeFragmentInnerFragment"
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_marginStart="32dp" android:layout_margin="16dp"
android:layout_marginEnd="32dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"
@ -39,5 +43,7 @@
</androidx.fragment.app.FragmentContainerView> </androidx.fragment.app.FragmentContainerView>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

@ -59,35 +59,24 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/labeled_values_recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="wrap_content"/>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<ImageView <ImageView
android:id="@+id/imageView3" android:id="@+id/locationBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginBottom="32dp"
android:src="@drawable/ic_baseline_chat_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView4"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="32dp" android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="32dp" android:layout_marginBottom="32dp"
android:src="@drawable/loacation_vector_asset" android:src="@drawable/loacation_vector_asset"
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_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

@ -1,27 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <fragment 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/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@drawable/map_fragment_gradient_background" tools:context=".fragments.mapFragment" />
tools:background="@drawable/map_fragment_gradient_background"
tools:context=".fragments.mapFragment">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/text_background_gradient"
android:padding="5dp"
android:text="Map Fragment"
android:textColor="@color/white"
android:textSize="26sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.23000002" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
card_view:cardCornerRadius="5dp"
android:backgroundTint="#00000000">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
android:background="@drawable/contrasting_gradient_background">
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:text="TextView"
android:textSize="40sp"
card_view:layout_constraintBottom_toBottomOf="parent"
card_view:layout_constraintStart_toStartOf="parent"
card_view:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="16dp"
android:text="TextView"
android:textSize="40sp"
card_view:layout_constraintBottom_toBottomOf="parent"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

@ -16,11 +16,8 @@
android:label="fragment_explore" android:label="fragment_explore"
tools:layout="@layout/fragment_explore"> tools:layout="@layout/fragment_explore">
<action <action
android:id="@+id/navigateToHomeFragment" android:id="@+id/navigateToMapFragment"
app:destination="@id/mapFragment" /> app:destination="@id/mapFragment" />
<action
android:id="@+id/action_exploreFragment_to_homeFragment"
app:destination="@id/homeFragment" />
<action <action
android:id="@+id/navigateToInfoFragment" android:id="@+id/navigateToInfoFragment"
app:destination="@id/infoFragment" /> app:destination="@id/infoFragment" />
@ -33,6 +30,9 @@
<action <action
android:id="@+id/action_homeFragment_to_chatFragment" android:id="@+id/action_homeFragment_to_chatFragment"
app:destination="@id/chatFragment" /> app:destination="@id/chatFragment" />
<action
android:id="@+id/homeFragment_to_mapFragment"
app:destination="@id/mapFragment" />
</fragment> </fragment>
<fragment <fragment
android:id="@+id/mapFragment" android:id="@+id/mapFragment"
@ -42,6 +42,12 @@
<action <action
android:id="@+id/action_mapFragment_to_exploreFragment" android:id="@+id/action_mapFragment_to_exploreFragment"
app:destination="@id/exploreFragment" /> app:destination="@id/exploreFragment" />
<argument
android:name="location"
app:argType="com.google.android.gms.maps.model.LatLng" />
<argument
android:name="markerTitle"
app:argType="string" />
</fragment> </fragment>
<fragment <fragment
android:id="@+id/settingsFragment" android:id="@+id/settingsFragment"
@ -75,8 +81,15 @@
android:name="com.example.wikispot.fragments.infoFragment" android:name="com.example.wikispot.fragments.infoFragment"
android:label="fragment_info" android:label="fragment_info"
tools:layout="@layout/fragment_info" > tools:layout="@layout/fragment_info" >
<argument
android:name="loadAutomatically"
app:argType="boolean"
android:defaultValue="false" />
<action <action
android:id="@+id/navigateBackToExploreFragmentFromInfoFragment" android:id="@+id/navigateBackToExploreFragment"
app:destination="@id/exploreFragment" /> app:destination="@id/exploreFragment" />
<action
android:id="@+id/infoFragment_to_mapFragment"
app:destination="@id/mapFragment" />
</fragment> </fragment>
</navigation> </navigation>

@ -1,14 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color> <color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color> <color name="white">#FFFFFFFF</color>
<!-- Light Theme --> <!-- Light Theme -->
<color name="primary">#4CAF50</color>
<color name="primaryVariant">#388E3C</color>
<color name="onPrimary">@color/white</color>
<color name="secondary">#E91E63</color>
<color name="secondaryVariant">#F48FB1</color>
<color name="onSecondary">@color/black</color>
<color name="bottomNavBarCheckedItemColor">#ECD21A1A</color> <color name="bottomNavBarCheckedItemColor">#ECD21A1A</color>
<color name="bottomNavBarItemColor">#320747</color> <color name="bottomNavBarItemColor">#320747</color>
<color name="bottomNavBarRippleColor">#33C4BCC9</color> <color name="bottomNavBarRippleColor">#33C4BCC9</color>
@ -45,9 +48,47 @@
<color name="infoFragmentGradientEndColor" >#96E7FF</color> <color name="infoFragmentGradientEndColor" >#96E7FF</color>
<!-- Dark Theme --> <!-- Dark Theme -->
<color name="primaryDark">#B078F4</color>
<color name="primaryVariantDark">#5100B3</color>
<color name="onPrimaryDark">@color/black</color>
<color name="secondaryDark">#FF03DAC5</color>
<color name="secondaryVariantDark">#FF03DAC5</color>
<color name="onSecondaryDark">@color/black</color>
<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">#4527A0</color>
<color name="textBackgroundGradientStartColorDark" >#80E5BEFF</color>
<color name="textBackgroundGradientEndColorDark" >#80FFB5F0</color>
<color name="bottomNavBarGradientStartColorDark" >#FCDD94</color>
<color name="bottomNavBarGradientEndColorDark" >#C5F8AB</color>
<color name="chatFragmentGradientStartColorDark" >#FCB0EF</color>
<color name="chatFragmentGradientCenterColorDark" >#9ECFFF</color>
<color name="chatFragmentGradientEndColorDark" >#9FE7FF</color>
<color name="exploreFragmentGradientStartColorDark" >#A1DEFC</color>
<color name="exploreFragmentGradientCenterColorDark" >#A5CBFF</color>
<color name="exploreFragmentGradientEndColorDark" >#F9B6F6</color>
<color name="homeFragmentGradientStartColorDark" >#83E1FF</color>
<color name="homeFragmentGradientCenterColorDark" >#9EC6FF</color>
<color name="homeFragmentGradientEndColorDark" >#FEBBFF</color>
<color name="mapFragmentGradientStartColorDark" >#FBBEFC</color>
<color name="mapFragmentGradientCenterColorDark" >#A5CBFF</color>
<color name="mapFragmentGradientEndColorDark" >#95DDFC</color>
<color name="settingsFragmentGradientStartColorDark" >#92EB97FC</color>
<color name="settingsFragmentGradientCenterColorDark" >#A198F9</color>
<color name="settingsFragmentGradientEndColorDark" >#74C7F7</color>
<color name="infoFragmentGradientStartColorDark" >#FFB6FB</color>
<color name="infoFragmentGradientCenterColorDark" >#A7D2FF</color>
<color name="infoFragmentGradientEndColorDark" >#96E7FF</color>
</resources> </resources>

@ -4,13 +4,13 @@
<style name="Theme.WikiSpot" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <style name="Theme.WikiSpot" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. --> <!-- Primary brand color. -->
<item name="colorPrimary">#4CAF50</item> <item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryVariant">#388E3C</item> <item name="colorPrimaryVariant">@color/primaryVariant</item>
<item name="colorOnPrimary">@color/white</item> <item name="colorOnPrimary">@color/onPrimary</item>
<!-- Secondary brand color. --> <!-- Secondary brand color. -->
<item name="colorSecondary">#E91E63</item> <item name="colorSecondary">@color/secondary</item>
<item name="colorSecondaryVariant">#F48FB1</item> <item name="colorSecondaryVariant">@color/secondaryVariant</item>
<item name="colorOnSecondary">@color/black</item> <item name="colorOnSecondary">@color/onSecondary</item>
<!-- For gradient Backgrounds --> <!-- For gradient Backgrounds -->
@ -66,45 +66,45 @@
<style name="Theme.WikiSpotDark" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <style name="Theme.WikiSpotDark" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. --> <!-- Primary brand color. -->
<item name="colorPrimary">#B078F4</item> <item name="colorPrimary">@color/primaryDark</item>
<item name="colorPrimaryVariant">#5100B3</item> <item name="colorPrimaryVariant">@color/primaryVariantDark</item>
<item name="colorOnPrimary">@color/black</item> <item name="colorOnPrimary">@color/onPrimaryDark</item>
<!-- Secondary brand color. --> <!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item> <item name="colorSecondary">@color/secondaryDark</item>
<item name="colorSecondaryVariant">@color/teal_200</item> <item name="colorSecondaryVariant">@color/secondaryVariantDark</item>
<item name="colorOnSecondary">@color/black</item> <item name="colorOnSecondary">@color/onSecondaryDark</item>
<!-- For gradient Backgrounds --> <!-- For gradient Backgrounds -->
<item name="textBackgroundGradientStartColor" >@color/textBackgroundGradientStartColor</item> <item name="textBackgroundGradientStartColor" >@color/textBackgroundGradientStartColorDark</item>
<item name="textBackgroundGradientEndColor" >@color/textBackgroundGradientEndColor</item> <item name="textBackgroundGradientEndColor" >@color/textBackgroundGradientEndColorDark</item>
<item name="bottomNavBarGradientStartColor" >@color/bottomNavBarGradientStartColor</item> <item name="bottomNavBarGradientStartColor" >@color/bottomNavBarGradientStartColorDark</item>
<item name="bottomNavBarGradientEndColor" >@color/bottomNavBarGradientEndColor</item> <item name="bottomNavBarGradientEndColor" >@color/bottomNavBarGradientEndColorDark</item>
<item name="chatFragmentGradientStartColor" >@color/chatFragmentGradientStartColor</item> <item name="chatFragmentGradientStartColor" >@color/chatFragmentGradientStartColorDark</item>
<item name="chatFragmentGradientCenterColor" >@color/chatFragmentGradientCenterColor</item> <item name="chatFragmentGradientCenterColor" >@color/chatFragmentGradientCenterColorDark</item>
<item name="chatFragmentGradientEndColor" >@color/chatFragmentGradientEndColor</item> <item name="chatFragmentGradientEndColor" >@color/chatFragmentGradientEndColorDark</item>
<item name="exploreFragmentGradientStartColor" >@color/exploreFragmentGradientStartColor</item> <item name="exploreFragmentGradientStartColor" >@color/exploreFragmentGradientStartColorDark</item>
<item name="exploreFragmentGradientCenterColor" >@color/exploreFragmentGradientCenterColor</item> <item name="exploreFragmentGradientCenterColor" >@color/exploreFragmentGradientCenterColorDark</item>
<item name="exploreFragmentGradientEndColor" >@color/exploreFragmentGradientEndColor</item> <item name="exploreFragmentGradientEndColor" >@color/exploreFragmentGradientEndColorDark</item>
<item name="homeFragmentGradientStartColor" >@color/homeFragmentGradientStartColor</item> <item name="homeFragmentGradientStartColor" >@color/homeFragmentGradientStartColorDark</item>
<item name="homeFragmentGradientCenterColor" >@color/homeFragmentGradientCenterColor</item> <item name="homeFragmentGradientCenterColor" >@color/homeFragmentGradientCenterColorDark</item>
<item name="homeFragmentGradientEndColor" >@color/homeFragmentGradientEndColor</item> <item name="homeFragmentGradientEndColor" >@color/homeFragmentGradientEndColorDark</item>
<item name="mapFragmentGradientStartColor" >@color/mapFragmentGradientStartColor</item> <item name="mapFragmentGradientStartColor" >@color/mapFragmentGradientStartColorDark</item>
<item name="mapFragmentGradientCenterColor" >@color/mapFragmentGradientCenterColor</item> <item name="mapFragmentGradientCenterColor" >@color/mapFragmentGradientCenterColorDark</item>
<item name="mapFragmentGradientEndColor" >@color/mapFragmentGradientEndColor</item> <item name="mapFragmentGradientEndColor" >@color/mapFragmentGradientEndColorDark</item>
<item name="settingsFragmentGradientStartColor" >@color/settingsFragmentGradientStartColor</item> <item name="settingsFragmentGradientStartColor" >@color/settingsFragmentGradientStartColorDark</item>
<item name="settingsFragmentGradientCenterColor" >@color/settingsFragmentGradientCenterColor</item> <item name="settingsFragmentGradientCenterColor" >@color/settingsFragmentGradientCenterColorDark</item>
<item name="settingsFragmentGradientEndColor" >@color/settingsFragmentGradientEndColor</item> <item name="settingsFragmentGradientEndColor" >@color/settingsFragmentGradientEndColorDark</item>
<item name="infoFragmentGradientStartColor" >@color/infoFragmentGradientStartColor</item> <item name="infoFragmentGradientStartColor" >@color/infoFragmentGradientStartColorDark</item>
<item name="infoFragmentGradientCenterColor" >@color/infoFragmentGradientCenterColor</item> <item name="infoFragmentGradientCenterColor" >@color/infoFragmentGradientCenterColorDark</item>
<item name="infoFragmentGradientEndColor" >@color/infoFragmentGradientEndColor</item> <item name="infoFragmentGradientEndColor" >@color/infoFragmentGradientEndColorDark</item>
<!-- BottomNavCheckedItemColor --> <!-- BottomNavCheckedItemColor -->
<item name="bottomNavBarCheckedItemColor">@color/bottomNavBarCheckedItemColorDark</item> <item name="bottomNavBarCheckedItemColor">@color/bottomNavBarCheckedItemColorDark</item>

@ -0,0 +1,20 @@
<resources>
<!--
TODO: Before you release your application, you need a Google Maps API key.
To do this, you can either add your release key credentials to your existing
key, or create a new key.
Note that this file specifies the API key for the release build target.
If you have previously set up a key for the debug target with the debug signing certificate,
you will also need to set up a key for your release certificate.
Follow the directions here:
https://developers.google.com/maps/documentation/android/signup
Once you have your key (it starts with "AIza"), replace the "google_maps_key"
string in this file.
-->
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">YOUR_KEY_HERE</string>
</resources>

@ -7,9 +7,12 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath "com.android.tools.build:gradle:4.1.1" classpath 'com.android.tools.build:gradle:4.1.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
def nav_version = "2.3.0-alpha04"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_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
} }