a lot of groups-related stuff, still WIP

This commit is contained in:
leca 2024-11-04 04:49:55 +03:00
parent f636511983
commit 4041e63a4b
17 changed files with 499 additions and 38 deletions

View File

@ -64,6 +64,14 @@
android:name=".activities.GroupActivity" android:name=".activities.GroupActivity"
android:exported="false" android:exported="false"
android:theme="@style/Theme.BarcodeScannerForEmployees"/> android:theme="@style/Theme.BarcodeScannerForEmployees"/>
<activity
android:name=".activities.ManageGroupActivity"
android:exported="false"
android:theme="@style/Theme.BarcodeScannerForEmployees"/>
<activity
android:name=".activities.MyGroupsActivity"
android:exported="false"
android:theme="@style/Theme.BarcodeScannerForEmployees"/>
<activity <activity
android:name=".activities.FullscreenActivity" android:name=".activities.FullscreenActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"

View File

@ -20,9 +20,10 @@ class Net {
val client = OkHttpClient() val client = OkHttpClient()
val formBody = FormBody.Builder() val body = FormBody.Builder()
formBody.add("barcode", barcode) .add("barcode", barcode)
val body = formBody.build() .build()
val request = Request.Builder() val request = Request.Builder()
.url(url) .url(url)
.post(body) .post(body)
@ -45,10 +46,10 @@ class Net {
thread { thread {
val client = OkHttpClient() val client = OkHttpClient()
val formBody = FormBody.Builder() val body = FormBody.Builder()
formBody.add("username", username) .add("username", username)
formBody.add("password", password) .add("password", password)
val body = formBody.build() .build()
val request = Request.Builder() val request = Request.Builder()
.url("https://$server/api/user/register") .url("https://$server/api/user/register")
@ -68,11 +69,10 @@ class Net {
thread { thread {
val client = OkHttpClient() val client = OkHttpClient()
val formBody = FormBody.Builder() val body = FormBody.Builder()
formBody.add("username", username) .add("username", username)
formBody.add("password", password) .add("password", password)
val body = formBody.build() .build()
val requestLogin = Request.Builder() val requestLogin = Request.Builder()
.url("https://$server/api/user/login") .url("https://$server/api/user/login")
.post(body) .post(body)
@ -92,21 +92,20 @@ class Net {
val client = OkHttpClient() val client = OkHttpClient()
val body = MultipartBody.Builder() val body = MultipartBody.Builder()
body.setType("multipart/form-data".toMediaType()) .setType("multipart/form-data".toMediaType())
body.addFormDataPart("file", imageFile.name, imageFile.asRequestBody("image/png".toMediaTypeOrNull())) .addFormDataPart("file", imageFile.name, imageFile.asRequestBody("image/png".toMediaTypeOrNull()))
body.addFormDataPart("groupId", groupId.toString()) .addFormDataPart("groupId", groupId.toString())
body.addFormDataPart("localId", abstractProduct.id.toString()) .addFormDataPart("localId", abstractProduct.id.toString())
body.addFormDataPart("barcode", abstractProduct.barcode) .addFormDataPart("barcode", abstractProduct.barcode)
body.addFormDataPart("name", abstractProduct.name) .addFormDataPart("name", abstractProduct.name)
body.addFormDataPart("net_weight", abstractProduct.netWeight.toString()) .addFormDataPart("net_weight", abstractProduct.netWeight.toString())
body.addFormDataPart("category", abstractProduct.category.toString()) .addFormDataPart("category", abstractProduct.category.toString())
body.addFormDataPart("unit", abstractProduct.unit.toString()) .addFormDataPart("unit", abstractProduct.unit.toString())
.build()
val requestBody = body.build()
val request = Request.Builder() val request = Request.Builder()
.url("https://$server/api/abstractproduct/create") .url("https://$server/api/abstractproduct/create")
.post(requestBody) .post(body)
.addHeader("Authorization", "Bearer $token") .addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language) .addHeader("accept-language", language)
.build() .build()
@ -129,7 +128,8 @@ class Net {
val requestBody = body.build() val requestBody = body.build()
val request = Request.Builder().url("https://$server/api/user/changeUsername") val request = Request.Builder()
.url("https://$server/api/user/changeUsername")
.post(requestBody) .post(requestBody)
.addHeader("Authorization", "Bearer $token") .addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language) .addHeader("accept-language", language)
@ -152,7 +152,8 @@ class Net {
val requestBody = body.build() val requestBody = body.build()
val request = Request.Builder().url("https://$server/api/user/changePassword") val request = Request.Builder()
.url("https://$server/api/user/changePassword")
.post(requestBody) .post(requestBody)
.addHeader("Authorization", "Bearer $token") .addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language) .addHeader("accept-language", language)
@ -173,7 +174,8 @@ class Net {
val requestBody = body.build() val requestBody = body.build()
val request = Request.Builder().url("https://$server/api/group/create/$name") val request = Request.Builder()
.url("https://$server/api/group/create/$name")
.post(requestBody) .post(requestBody)
.addHeader("Authorization", "Bearer $token") .addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language) .addHeader("accept-language", language)
@ -185,6 +187,28 @@ class Net {
return changeGroupPassword(name, password) return changeGroupPassword(name, password)
} }
fun joinGroup(id: Int, password: String): Response {
lateinit var response: Response
thread {
val client = OkHttpClient()
val body = FormBody.Builder()
.add("password", password)
.build()
val request = Request.Builder()
.url("https://$server/api/group/join/$id")
.post(body)
.addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
return response
}
fun changeGroupPassword(name: String, password: String): Response { fun changeGroupPassword(name: String, password: String): Response {
lateinit var response: Response lateinit var response: Response
@ -199,7 +223,8 @@ class Net {
val requestBody = body.build() val requestBody = body.build()
val request = Request.Builder().url("https://$server/api/group/password/$groupId") val request = Request.Builder()
.url("https://$server/api/group/password/$groupId")
.post(requestBody) .post(requestBody)
.addHeader("Authorization", "Bearer $token") .addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language) .addHeader("accept-language", language)
@ -216,7 +241,8 @@ class Net {
thread { thread {
val client = OkHttpClient() val client = OkHttpClient()
val request = Request.Builder().url("https://$server/api/group/byName/$name") val request = Request.Builder()
.url("https://$server/api/group/byName/$name")
.get() .get()
.addHeader("Authorization", "Bearer $token") .addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language) .addHeader("accept-language", language)
@ -228,4 +254,100 @@ class Net {
return responseText return responseText
} }
fun getGroupName(id: Int) : String {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://$server/api/group/byId/$id")
.get()
.addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
val responseText = response.body!!.string()
return responseText
}
fun getUsersInGroup(groupId: Int): Response {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://$server/api/group/getUsers/$groupId")
.get()
.addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
return response
}
fun getMyGroups(): Response {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://$server/api/user/myGroups")
.get()
.addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
return response
}
fun getUsernameById(userId: Int): Response {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://$server/api/user/byId/$userId")
.get()
.addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
return response
}
fun getGroupAdminId(groupId: Int): Response {
lateinit var response: Response
thread {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://$server/api/group/adminId/$groupId")
.get()
.addHeader("Authorization", "Bearer $token")
.addHeader("accept-language", language)
.build()
response = client.newCall(request).execute()
}.join()
return response
}
} }

View File

@ -95,3 +95,7 @@ fun getUnitNameById (context: Context, id: Int): String {
else -> { "" } else -> { "" }
} }
} }
fun parseArray(input: String): IntArray {
return input.trim('[', ']').split(",").map { it.trim().toInt() }.toIntArray()
}

View File

@ -40,14 +40,43 @@ class GroupActivity : AppCompatActivity() {
val response = n.createGroup(groupName, groupPassword) val response = n.createGroup(groupName, groupPassword)
val responseText = response.body!!.string() val responseText = response.body!!.string()
Toast.makeText(this, responseText, Toast.LENGTH_LONG).show()
if (response.code == 200) { if (response.code == 200) {
Toast.makeText(this, responseText, Toast.LENGTH_LONG).show() val currentGroups = sharedPreferences.getStringSet("groups", mutableSetOf())
sharedPreferences.edit().putStringSet("groups", setOf(responseText)) currentGroups!!.add(responseText)
sharedPreferences.edit().putStringSet("groups", currentGroups).apply()
sharedPreferences.edit().putString("currentGroup", responseText).apply()
val intent = Intent(this, MainActivity::class.java) val intent = Intent(this, MainActivity::class.java)
startActivity(intent) startActivity(intent)
finish() finish()
} else {
Toast.makeText(this, responseText, Toast.LENGTH_LONG).show()
}
}
binding.joinGroupButton.setOnClickListener {
val groupName = binding.groupNameTextEdit.text.toString()
val groupPassword = binding.groupPasswordTextEdit.text.toString()
val n = Net()
n.language = sharedPreferences.getString("language", "en-US")!!
n.server = sharedPreferences.getString("server", "")!!
n.token = sharedPreferences.getString("token", "")!!
val groupId = n.getGroupId(groupName).toInt()
val response = n.joinGroup(groupId, groupPassword)
val responseText = response.body!!.string()
if (response.code == 200) {
val currentGroups = sharedPreferences.getStringSet("groups", mutableSetOf())
currentGroups!!.add(groupId.toString())
sharedPreferences.edit().putStringSet("groups", currentGroups).apply()
sharedPreferences.edit().putString("currentGroup", responseText).apply()
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
} else {
Toast.makeText(this, responseText, Toast.LENGTH_LONG).show()
} }
} }
} }

View File

@ -10,6 +10,8 @@ import androidx.security.crypto.MasterKeys
import org.foxarmy.barcodescannerforemployees.Net import org.foxarmy.barcodescannerforemployees.Net
import org.foxarmy.barcodescannerforemployees.R import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.databinding.ActivityLoginBinding import org.foxarmy.barcodescannerforemployees.databinding.ActivityLoginBinding
import org.foxarmy.barcodescannerforemployees.parseArray
import org.json.JSONObject
class LoginActivity : AppCompatActivity() { class LoginActivity : AppCompatActivity() {
@ -49,8 +51,17 @@ class LoginActivity : AppCompatActivity() {
if (response.code != 200) { if (response.code != 200) {
Toast.makeText(this, responseText, Toast.LENGTH_SHORT).show() Toast.makeText(this, responseText, Toast.LENGTH_SHORT).show()
} else { } else {
sharedPreferences.edit().putString("token", responseText).apply() val json = JSONObject(responseText)
sharedPreferences.edit().putString("servre", server).apply() sharedPreferences.edit().putString("token", json["token"].toString()).apply()
n.token = json["token"].toString()
sharedPreferences.edit().putInt("userId", json["id"].toString().toInt()).apply()
sharedPreferences.edit().putString("server", server).apply()
val r = n.getMyGroups().body!!.string()
val myGroups = parseArray(r)
sharedPreferences.edit().putStringSet("groups", myGroups.map { a -> a.toString()}.toSet())
val intent = Intent(this, MainActivity::class.java) val intent = Intent(this, MainActivity::class.java)
startActivity(intent) startActivity(intent)
finish() finish()
@ -73,8 +84,9 @@ class LoginActivity : AppCompatActivity() {
if (response.code != 200) { if (response.code != 200) {
Toast.makeText(this, responseText, Toast.LENGTH_SHORT).show(); Toast.makeText(this, responseText, Toast.LENGTH_SHORT).show();
} else { } else {
val token = n.login(username, password) sharedPreferences.edit().putInt("userId", responseText.toInt()).apply()
sharedPreferences.edit().putString("token", token.body!!.string()).apply() val token = JSONObject(n.login(username, password).body!!.string())["token"].toString()
sharedPreferences.edit().putString("token", token).apply()
sharedPreferences.edit().putString("server", server).apply() sharedPreferences.edit().putString("server", server).apply()
val intent = Intent(this, GroupActivity::class.java) val intent = Intent(this, GroupActivity::class.java)

View File

@ -118,7 +118,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
intent = Intent(this, AccountSettingsActivity::class.java) intent = Intent(this, AccountSettingsActivity::class.java)
} }
R.id.nav_groups -> { R.id.nav_groups -> {
intent = Intent(this, AccountSettingsActivity::class.java) intent = Intent(this, MyGroupsActivity::class.java)
} }
R.id.nav_settings -> { R.id.nav_settings -> {
//TODO: Settings //TODO: Settings

View File

@ -0,0 +1,78 @@
package org.foxarmy.barcodescannerforemployees.activities
import android.content.Context
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys
import org.foxarmy.barcodescannerforemployees.Net
import org.foxarmy.barcodescannerforemployees.databinding.ActivityManageGroupBinding
import org.foxarmy.barcodescannerforemployees.parseArray
import org.foxarmy.barcodescannerforemployees.views.GroupMemberView
class ManageGroupActivity : AppCompatActivity(){
private lateinit var binding: ActivityManageGroupBinding
private var isAdmin: Boolean = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityManageGroupBinding.inflate(layoutInflater)
setContentView(binding.root)
val groupId = intent.extras!!.getInt("groupId")
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
val sharedPreferences = EncryptedSharedPreferences.create(
"sensitive",
masterKeyAlias,
applicationContext,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
val net = Net()
net.token = sharedPreferences.getString("token", "")!!
net.server = sharedPreferences.getString("server", "")!!
net.language = sharedPreferences.getString("language", "en-US")!!
val users = parseArray(net.getUsersInGroup(groupId).body!!.string())
for (user in users) {
val groupMemberView = GroupMemberView(this, this as Context, net.getUsernameById(user).body!!.string(), user)
binding.groupsContent.addView(groupMemberView)
}
isAdmin = amIAnAdminIn(groupId)
if (!isAdmin) {
binding.renameButton.visibility = View.GONE
}
}
fun amIAnAdminIn(groupId: Int): Boolean {
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
val sharedPreferences = EncryptedSharedPreferences.create(
"sensitive",
masterKeyAlias,
applicationContext,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
val net = Net()
net.token = sharedPreferences.getString("token", "")!!
net.server = sharedPreferences.getString("server", "")!!
net.language = sharedPreferences.getString("language", "en-US")!!
val result = sharedPreferences.getInt("userId", 0) == net.getGroupAdminId(groupId).body!!.string().toInt()
return result
}
}

View File

@ -0,0 +1,57 @@
package org.foxarmy.barcodescannerforemployees.activities
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys
import org.foxarmy.barcodescannerforemployees.Net
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.databinding.ActivityMyGroupsBinding
import org.foxarmy.barcodescannerforemployees.parseArray
import org.foxarmy.barcodescannerforemployees.views.GroupView
class MyGroupsActivity : AppCompatActivity(){
private lateinit var binding: ActivityMyGroupsBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMyGroupsBinding.inflate(layoutInflater)
setContentView(binding.root)
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
val sharedPreferences = EncryptedSharedPreferences.create(
"sensitive",
masterKeyAlias,
applicationContext,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
val net = Net()
net.token = sharedPreferences.getString("token", "")!!
net.server = sharedPreferences.getString("server", "")!!
net.language = sharedPreferences.getString("language", "en-US")!!
val groups = parseArray(net.getMyGroups().body!!.string())
val container = findViewById<LinearLayout>(R.id.groupsLayout)
for (group in groups) {
val groupView = GroupView(this, this as Context, net.getGroupName(group), group)
container.addView(groupView)
}
binding.newGroup.setOnClickListener {
val intent = Intent(this, GroupActivity::class.java)
startActivity(intent)
}
}
}

View File

@ -3,6 +3,7 @@ package org.foxarmy.barcodescannerforemployees.activities
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log
import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys import androidx.security.crypto.MasterKeys
@ -22,7 +23,7 @@ class NavigatorActivity : Activity() {
startActivity(intent); startActivity(intent);
// finish(); finish();
} }
private fun isAuthenticated(): Boolean { private fun isAuthenticated(): Boolean {
@ -52,6 +53,7 @@ class NavigatorActivity : Activity() {
) )
val groups = sharedPreferences.getStringSet("groups", emptySet()) val groups = sharedPreferences.getStringSet("groups", emptySet())
Log.d("QWERTYUIOP", groups.toString())
return groups!!.isNotEmpty() return groups!!.isNotEmpty()
} }
} }

View File

@ -0,0 +1,25 @@
package org.foxarmy.barcodescannerforemployees.views
import android.app.Activity
import android.content.Context
import android.view.LayoutInflater
import android.widget.LinearLayout
import android.widget.TextView
import org.foxarmy.barcodescannerforemployees.R
class GroupMemberView : LinearLayout {
private var username: String
private var userId: Int
constructor(activity: Activity, context: Context, username: String, userId: Int) : super(context) {
this.username = username
this.userId = userId
val inflater: LayoutInflater = activity.layoutInflater
inflater.inflate(R.layout.group_member_view, this)
findViewById<TextView>(R.id.userNameTextView).text = username
}
}

View File

@ -0,0 +1,37 @@
package org.foxarmy.barcodescannerforemployees.views
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import org.foxarmy.barcodescannerforemployees.R
import org.foxarmy.barcodescannerforemployees.activities.ManageGroupActivity
class GroupView : LinearLayout {
private var name: String
private var id: Int
constructor(activity: Activity, context: Context, name: String, id: Int) : super(context) {
this.name = name
this.id = id
val inflater: LayoutInflater = activity.layoutInflater
inflater.inflate(R.layout.group_view, this)
findViewById<TextView>(R.id.nameTextView).text = name
setOnClickListener {
val intent = Intent(activity, ManageGroupActivity::class.java)
val extras = Bundle()
extras.putInt("groupId", id)
intent.putExtras(extras)
ContextCompat.startActivity(context, intent, extras)
}
}
}

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="@string/leave_group"
android:layout_width="91dp"
android:layout_height="wrap_content" android:id="@+id/leaveButton"
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="12dp"
app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="48dp"
app:layout_constraintEnd_toStartOf="@+id/renameButton" android:layout_marginEnd="12dp"/>
<Button
android:text="@string/rename_group"
android:layout_width="91dp"
android:layout_height="wrap_content" android:id="@+id/renameButton"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="48dp"
app:layout_constraintStart_toEndOf="@+id/leaveButton" app:layout_constraintEnd_toStartOf="@+id/button3"
android:visibility="visible"/>
<Button
android:text="Button"
android:layout_width="91dp"
android:layout_height="wrap_content" android:id="@+id/button3"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="48dp"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="12dp"
app:layout_constraintStart_toEndOf="@+id/renameButton" android:visibility="gone"
android:layout_marginStart="12dp"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/leaveButton"
android:layout_marginTop="48dp" android:id="@+id/membersScrollView">
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="vertical" android:id="@+id/groupsContent"/>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="@string/join_or_create_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/newGroup"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="24dp"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content" android:id="@+id/groupsContent"
app:layout_constraintTop_toBottomOf="@+id/newGroup" android:layout_marginTop="16dp">
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="vertical" android:id="@+id/groupsLayout"/>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="User"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/userNameTextView" android:layout_weight="1"
android:textSize="30sp"/>
</LinearLayout>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="Group"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:id="@+id/nameTextView" android:textSize="30sp"/>
</LinearLayout>

View File

@ -107,6 +107,10 @@
<string name="group_password">Group password</string> <string name="group_password">Group password</string>
<string name="create_group">Create group</string> <string name="create_group">Create group</string>
<string name="join_group">Join group</string> <string name="join_group">Join group</string>
<string name="leave">Leave</string>
<string name="leave_group">Leave group</string>
<string name="rename_group">Rename group</string>
<string name="join_or_create_group">Join or create a group</string>
<string-array name="languages"> <string-array name="languages">
<item>en-US</item> <item>en-US</item>
<item>ru-RU</item> <item>ru-RU</item>

View File

@ -105,6 +105,10 @@
<string name="group_password">Group password</string> <string name="group_password">Group password</string>
<string name="create_group">Create group</string> <string name="create_group">Create group</string>
<string name="join_group">Join group</string> <string name="join_group">Join group</string>
<string name="leave">Leave</string>
<string name="leave_group">Leave group</string>
<string name="rename_group">Rename group</string>
<string name="join_or_create_group">Join or create a group</string>
<string-array name="languages"> <string-array name="languages">
<item>en-US</item> <item>en-US</item>
<item>ru-RU</item> <item>ru-RU</item>