working on network and UI
This commit is contained in:
parent
3d4f86085e
commit
a0d96da9e4
|
@ -50,13 +50,16 @@ dependencies {
|
|||
implementation(libs.androidx.activity)
|
||||
implementation(libs.androidx.legacy.support.v4)
|
||||
implementation(libs.androidx.fragment)
|
||||
implementation(libs.androidx.material3.android)
|
||||
testImplementation(libs.junit)
|
||||
implementation(libs.volley)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
implementation(libs.zxing.android.embedded)
|
||||
implementation("com.google.zxing:core:3.4.1")
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
|
||||
implementation("com.google.android.material:material:1.3.0-alpha03")
|
||||
implementation(libs.androidx.security.crypto)
|
||||
implementation(libs.okhttp)
|
||||
// Barcode scanning API
|
||||
implementation (libs.barcode.scanning)
|
||||
|
||||
|
|
|
@ -48,6 +48,14 @@
|
|||
android:name=".activities.FindBarcodelessAbstractProduct"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.BarcodeScannerForEmployees"/>
|
||||
<activity
|
||||
android:name=".activities.MainActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.BarcodeScannerForEmployees"/>
|
||||
<activity
|
||||
android:name=".activities.LoginActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.BarcodeScannerForEmployees"/>
|
||||
<activity
|
||||
android:name=".activities.FullscreenActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
|
@ -70,7 +78,7 @@
|
|||
</provider>
|
||||
|
||||
<activity
|
||||
android:name=".activities.MainActivity"
|
||||
android:name=".activities.NavigatorActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.BarcodeScannerForEmployees">
|
||||
<intent-filter>
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
package org.foxarmy.barcodescannerforemployees
|
||||
|
||||
import android.util.Log
|
||||
import okhttp3.*
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.RequestBody.Companion.asRequestBody
|
||||
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
|
||||
import java.io.File
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class Net {
|
||||
|
||||
fun requestProductFromOnlineDB(barcode: String): String {
|
||||
var response = ""
|
||||
thread {
|
||||
val url = "https://ean-online.ru/match.php"
|
||||
|
||||
val client = OkHttpClient()
|
||||
|
||||
val formBody = FormBody.Builder()
|
||||
formBody.add("barcode", barcode)
|
||||
val body = formBody.build()
|
||||
val request = Request.Builder()
|
||||
.url(url)
|
||||
.post(body)
|
||||
.addHeader("referer", "https://ean-online.ru")
|
||||
.build()
|
||||
|
||||
response = client.newCall(request).execute().body!!.string()
|
||||
}.join()
|
||||
|
||||
return if (response == "") {
|
||||
"Not found 404"
|
||||
} else {
|
||||
response
|
||||
}
|
||||
}
|
||||
|
||||
fun registerAccount(server: String, username: String, password: String): String {
|
||||
var token = ""
|
||||
lateinit var response: Response
|
||||
thread {
|
||||
val client = OkHttpClient()
|
||||
|
||||
val formBody = FormBody.Builder()
|
||||
formBody.add("username", username)
|
||||
formBody.add("password", password)
|
||||
val body = formBody.build()
|
||||
|
||||
val request = Request.Builder()
|
||||
.url("https://$server/api/user/register")
|
||||
.post(body)
|
||||
.addHeader("content-type", "application/x-www-form-urlencoded")
|
||||
.build()
|
||||
|
||||
response = client.newCall(request).execute()
|
||||
}.join()
|
||||
|
||||
return when (response.code) {
|
||||
200 -> {
|
||||
login(server, username, password)
|
||||
}
|
||||
400 -> {
|
||||
"Such username exists"
|
||||
}
|
||||
else -> {
|
||||
"Unknown error"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun login(server: String, username: String, password: String): String {
|
||||
lateinit var response: Response
|
||||
thread {
|
||||
val client = OkHttpClient()
|
||||
|
||||
val formBody = FormBody.Builder()
|
||||
formBody.add("username", username)
|
||||
formBody.add("password", password)
|
||||
val body = formBody.build()
|
||||
|
||||
val requestLogin = Request.Builder()
|
||||
.url("https://$server/api/user/login")
|
||||
.post(body)
|
||||
.addHeader("content-type", "application/x-www-form-urlencoded")
|
||||
.build()
|
||||
response = client.newCall(requestLogin).execute()
|
||||
}.join()
|
||||
|
||||
return response.body!!.string()
|
||||
}
|
||||
|
||||
fun uploadAbstractProduct(server: String, groupId: Int, abstractProduct: AbstractProduct, imageFile: File, token: String): String {
|
||||
lateinit var response: Response
|
||||
|
||||
thread {
|
||||
val client = OkHttpClient()
|
||||
|
||||
val body = MultipartBody.Builder()
|
||||
body.setType("multipart/form-data".toMediaType())
|
||||
body.addFormDataPart("file", imageFile.name, imageFile.asRequestBody("image/png".toMediaTypeOrNull()))
|
||||
body.addFormDataPart("groupId", groupId.toString())
|
||||
body.addFormDataPart("localId", abstractProduct.id.toString())
|
||||
body.addFormDataPart("barcode", abstractProduct.barcode)
|
||||
body.addFormDataPart("name", abstractProduct.name)
|
||||
body.addFormDataPart("net_weight", abstractProduct.netWeight.toString())
|
||||
body.addFormDataPart("image_filename", abstractProduct.imageHash)
|
||||
body.addFormDataPart("category", abstractProduct.category.toString())
|
||||
body.addFormDataPart("unit", abstractProduct.unit.toString())
|
||||
|
||||
val requestBody = body.build()
|
||||
|
||||
val request = Request.Builder()
|
||||
.url("https://$server/api/abstractproduct/create")
|
||||
.post(requestBody)
|
||||
.addHeader("Authorization", "Bearer $token")
|
||||
.build()
|
||||
|
||||
response = client.newCall(request).execute()
|
||||
}.join()
|
||||
|
||||
val responseText = response.body!!.string()
|
||||
|
||||
return responseText
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package org.foxarmy.barcodescannerforemployees
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import com.android.volley.toolbox.StringRequest
|
||||
import com.android.volley.toolbox.Volley
|
||||
|
||||
class Requester constructor(var siteName: String, var endpoint: String) {
|
||||
var response = ""
|
||||
|
||||
fun request(context: Context, barcode: String) {
|
||||
val url = "${siteName}/${endpoint}"
|
||||
|
||||
val volleyQueue = Volley.newRequestQueue(context)
|
||||
val stringRequest = object: StringRequest(
|
||||
Method.POST, url, { resp ->
|
||||
run {
|
||||
response =
|
||||
if (resp == "") {
|
||||
"Not found 404"
|
||||
} else {
|
||||
resp
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
Toast.makeText(context, "Cannot make request", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
) {
|
||||
override fun getHeaders(): Map<String, String> {
|
||||
return mapOf("referer" to "$siteName/")
|
||||
}
|
||||
|
||||
public override fun getParams(): MutableMap<String, String> {
|
||||
return mutableMapOf("barcode" to barcode)
|
||||
}
|
||||
}
|
||||
volleyQueue.add(stringRequest)
|
||||
}
|
||||
}
|
|
@ -14,15 +14,19 @@ import androidx.appcompat.app.AlertDialog
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.security.crypto.EncryptedSharedPreferences
|
||||
import androidx.security.crypto.MasterKeys
|
||||
import com.journeyapps.barcodescanner.ScanContract
|
||||
import com.journeyapps.barcodescanner.ScanIntentResult
|
||||
import com.journeyapps.barcodescanner.ScanOptions
|
||||
import okhttp3.internal.http.hasBody
|
||||
import org.foxarmy.barcodescannerforemployees.*
|
||||
import org.foxarmy.barcodescannerforemployees.dataclasses.AbstractProduct
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
import kotlin.concurrent.thread
|
||||
import kotlin.math.abs
|
||||
|
||||
class AddAbstractProductActivity : AppCompatActivity() {
|
||||
private lateinit var imageView: ImageView
|
||||
|
@ -147,7 +151,21 @@ class AddAbstractProductActivity : AppCompatActivity() {
|
|||
arrayOf(abstractProduct!!.id.toString())
|
||||
)
|
||||
} else if (action == "new" || action == "new_from_barcode"){
|
||||
db.insert(AbstractProductContract.AbstractProductEntry.TABLE_NAME, null, values)
|
||||
val id = db.insert(AbstractProductContract.AbstractProductEntry.TABLE_NAME, null, values)
|
||||
val n = Net()
|
||||
val abstractProduct = AbstractProduct(id.toInt(), barcode, productName, netWeight.toString().toDouble(), pictureFile.nameWithoutExtension, categorySpinner.selectedItemPosition, unitTypeSpinner.selectedItemPosition)
|
||||
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
||||
|
||||
val sharedPreferences = EncryptedSharedPreferences.create(
|
||||
// passing a file name to share a preferences
|
||||
"sensitive",
|
||||
masterKeyAlias,
|
||||
applicationContext,
|
||||
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
|
||||
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
|
||||
)
|
||||
val token = sharedPreferences.getString("token", "")
|
||||
val response = n.uploadAbstractProduct("bsfe.foxarmy.org", 1, abstractProduct, File(pictureFile.absolutePath), token!!);
|
||||
}
|
||||
|
||||
finish()
|
||||
|
@ -165,8 +183,10 @@ class AddAbstractProductActivity : AppCompatActivity() {
|
|||
|
||||
fun performRequest(barcode: String) {
|
||||
barcodeText.setText(this.barcode)
|
||||
val requester = Requester("https://ean-online.ru", "match.php")
|
||||
requester.request(this, barcode)
|
||||
val net = Net();
|
||||
val result = net.requestProductFromOnlineDB(barcode)
|
||||
Log.d("QWERTYUIOP", "Result of request: $result")
|
||||
|
||||
var abstractProduct: AbstractProduct
|
||||
|
||||
if (DBStorageController(this).findAbstractProductByBarcode(
|
||||
|
@ -194,10 +214,7 @@ class AddAbstractProductActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
thread {
|
||||
// Я сам в ахуях какой это костыль, пока хз как фиксить, потом придумаю :))
|
||||
while (requester.response == "") {
|
||||
}
|
||||
if (requester.response == "Not found 404") {
|
||||
if (result == "Not found 404") {
|
||||
runOnUiThread {
|
||||
Toast.makeText(this, getString(R.string.no_product_in_online_database), Toast.LENGTH_LONG)
|
||||
.show()
|
||||
|
@ -207,8 +224,7 @@ class AddAbstractProductActivity : AppCompatActivity() {
|
|||
return@thread
|
||||
}
|
||||
|
||||
abstractProduct = Parser().parse(requester.response)
|
||||
requester.response = ""
|
||||
abstractProduct = Parser().parse(result)
|
||||
runOnUiThread {
|
||||
productNameText.text = abstractProduct.name
|
||||
netWeightText.text = abstractProduct.netWeight.toString()
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package org.foxarmy.barcodescannerforemployees.activities
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
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.ActivityLoginBinding
|
||||
|
||||
class LoginActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityLoginBinding;
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = ActivityLoginBinding.inflate(layoutInflater);
|
||||
setContentView(binding.root)
|
||||
|
||||
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
||||
|
||||
val sharedPreferences = EncryptedSharedPreferences.create(
|
||||
// passing a file name to share a preferences
|
||||
"sensitive",
|
||||
masterKeyAlias,
|
||||
applicationContext,
|
||||
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
|
||||
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
|
||||
)
|
||||
|
||||
binding.loginButton.setOnClickListener {
|
||||
val server = binding.serverTextEdit.text.toString()
|
||||
val username = binding.usernameTextEdit.text.toString()
|
||||
val password = binding.passwordTextEdit.text.toString()
|
||||
|
||||
val n = Net()
|
||||
|
||||
val response = n.login(server, username, password)
|
||||
|
||||
if (response == "Wrong password") {
|
||||
Toast.makeText(this, getString(R.string.wrong_password), Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
sharedPreferences.edit().putString("token", response).apply()
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
binding.registerButton.setOnClickListener {
|
||||
val server = binding.serverTextEdit.text.toString()
|
||||
val username = binding.usernameTextEdit.text.toString()
|
||||
val password = binding.passwordTextEdit.text.toString()
|
||||
|
||||
val n = Net()
|
||||
|
||||
val response = n.registerAccount(server, username, password);
|
||||
|
||||
if (response == "Such username exists") {
|
||||
Toast.makeText(this, getString(R.string.username_already_exists), Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
sharedPreferences.edit().putString("token", response).apply()
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -69,6 +69,7 @@ class MainActivity : AppCompatActivity() {
|
|||
extras.putParcelable("product", null)
|
||||
addProductIntent.putExtras(extras)
|
||||
ContextCompat.startActivity(this, addProductIntent, extras)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package org.foxarmy.barcodescannerforemployees.activities
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.security.crypto.EncryptedSharedPreferences
|
||||
import androidx.security.crypto.MasterKeys
|
||||
|
||||
class NavigatorActivity : Activity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
var intent = Intent(this, LoginActivity::class.java)
|
||||
|
||||
if (isAuthenticated()) {
|
||||
intent = Intent(this, MainActivity::class.java);
|
||||
}
|
||||
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
fun isAuthenticated(): Boolean {
|
||||
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
||||
|
||||
val sharedPreferences = EncryptedSharedPreferences.create(
|
||||
// passing a file name to share a preferences
|
||||
"sensitive",
|
||||
masterKeyAlias,
|
||||
applicationContext,
|
||||
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
|
||||
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
|
||||
)
|
||||
|
||||
val jwt = sharedPreferences.getString("token", "")
|
||||
return jwt != ""
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?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/register"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" android:id="@+id/registerButton"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/loginButton" app:layout_constraintHorizontal_bias="0.15"
|
||||
app:layout_constraintBottom_toTopOf="@+id/offlineButton" android:layout_marginBottom="64dp"/>
|
||||
<Button
|
||||
android:text="@string/login"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" android:id="@+id/loginButton"
|
||||
app:layout_constraintStart_toEndOf="@+id/registerButton" app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginStart="2dp"
|
||||
app:layout_constraintHorizontal_bias="0.1" app:layout_constraintBottom_toTopOf="@+id/offlineButton"
|
||||
android:layout_marginBottom="64dp"/>
|
||||
<Button
|
||||
android:text="@string/offline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" android:id="@+id/offlineButton"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginBottom="300dp"/>
|
||||
<EditText
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="50dp"
|
||||
android:inputType="text"
|
||||
android:ems="10"
|
||||
android:id="@+id/usernameTextEdit"
|
||||
app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"
|
||||
android:hint="@string/username" app:layout_constraintBottom_toTopOf="@+id/passwordTextEdit"
|
||||
android:layout_marginBottom="16dp"/>
|
||||
<EditText
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="50dp"
|
||||
android:inputType="textPassword"
|
||||
android:ems="10"
|
||||
android:id="@+id/passwordTextEdit"
|
||||
android:hint="@string/password" app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toTopOf="@+id/registerButton"
|
||||
android:layout_marginBottom="24dp"/>
|
||||
<EditText
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:ems="10"
|
||||
android:id="@+id/serverTextEdit"
|
||||
app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/usernameTextEdit" android:layout_marginBottom="16dp"
|
||||
android:hint="@string/server" android:text="bsfe.foxarmy.org"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,61 +1,74 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
<androidx.drawerlayout.widget.DrawerLayout
|
||||
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"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".activities.MainActivity">
|
||||
tools:context=".activities.MainActivity"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" android:id="@+id/storageLayout">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
>
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"/>
|
||||
android:layout_height="match_parent" android:id="@+id/storageLayout">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tab_tablayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabIndicatorColor="#FFF"
|
||||
app:tabIndicatorHeight="3dp"
|
||||
app:tabMode="fixed" />
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:id="@+id/appBarLayout">
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"/>
|
||||
|
||||
<!-- <include layout="@layout/content_storage"/>-->
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/tab_viewpager"
|
||||
android:layout_width="match_parent"
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tab_tablayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabIndicatorColor="#FFF"
|
||||
app:tabIndicatorHeight="3dp"
|
||||
app:tabMode="fixed"/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/tab_viewpager"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="777dp"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" android:layout_gravity="bottom"
|
||||
android:layout_marginTop="2dp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/appBarLayout"
|
||||
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="6dp"
|
||||
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="6dp"/>
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/new_element_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
app:srcCompat="@android:drawable/ic_input_add"
|
||||
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="16dp" android:layout_marginBottom="16dp"/>
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true" app:srcCompat="@android:drawable/ic_menu_my_calendar"
|
||||
android:id="@+id/expiryCalendarFab" android:layout_gravity="bottom|end"
|
||||
app:layout_constraintBottom_toTopOf="@+id/new_element_fab" android:layout_marginBottom="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="16dp"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<!-- <include layout="@layout/content_storage"/>-->
|
||||
|
||||
<com.google.android.material.navigation.NavigationView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="5dp"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
android:layout_gravity="start"
|
||||
app:menu="@menu/drawer_menu" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/new_element_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="@dimen/fab_margin"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:srcCompat="@android:drawable/ic_input_add"/>
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true" app:srcCompat="@android:drawable/ic_menu_my_calendar"
|
||||
android:id="@+id/expiryCalendarFab" android:layout_gravity="bottom|end"
|
||||
tools:layout_editor_absoluteY="742dp" tools:layout_editor_absoluteX="337dp"
|
||||
android:layout_marginBottom="84dp" android:layout_marginRight="16dp"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_account"
|
||||
android:title="@string/my_account" />
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_settings"
|
||||
android:title="@string/settings" />
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_logout"
|
||||
android:title="@string/my_groups" />
|
||||
</menu>
|
|
@ -3,7 +3,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="org.foxarmy.barcodescannerforemployees.activities.MainActivity">
|
||||
<item android:id="@+id/action_settings"
|
||||
android:title="@string/action_settings"
|
||||
android:title="@string/settings"
|
||||
android:orderInCategory="100"
|
||||
app:showAsAction="never"/>
|
||||
<item android:id="@+id/action_delete" android:title="@string/delete_menu"/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">СканнерШтрихкодовДляРаботников</string>
|
||||
<string name="action_settings">Настройки</string>
|
||||
<string name="settings">Настройки</string>
|
||||
<string name="first_fragment_label">Добавить продукт</string>
|
||||
<string name="second_fragment_label">Продукты</string>
|
||||
<string name="scan_label">Сканировать</string>
|
||||
|
@ -87,6 +87,16 @@
|
|||
ошибка сканирования или введите данные вручную
|
||||
</string>
|
||||
<string name="abstract_product_request">Пожалуйста, отсканируйте штрихкод, чтобы добавить продукт</string>
|
||||
<string name="no_barcode">No barcode present</string>
|
||||
<string name="no_barcode_button">No barcode</string>
|
||||
<string name="no_barcode">Нет штрихкода</string>
|
||||
<string name="no_barcode_button">Без штрихкода</string>
|
||||
<string name="register">Зарегистрироваться</string>
|
||||
<string name="login">Войти</string>
|
||||
<string name="offline">Оффлайн</string>
|
||||
<string name="username">Имя пользователя</string>
|
||||
<string name="password">Пароль</string>
|
||||
<string name="username_already_exists">Имя пользователя занято</string>
|
||||
<string name="wrong_password">Неправильный пароль</string>
|
||||
<string name="server">Сервер</string>
|
||||
<string name="my_account">Мой аккаунт</string>
|
||||
<string name="my_groups">Мои группы</string>
|
||||
</resources>
|
|
@ -1,6 +1,6 @@
|
|||
<resources>
|
||||
<string name="app_name">BarcodeScannerForEmployees</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="first_fragment_label">Add new product</string>
|
||||
<string name="second_fragment_label">Products</string>
|
||||
<string name="netWeight">Net weight</string>
|
||||
|
@ -87,4 +87,14 @@
|
|||
<string name="abstract_product_request">Please, scan a barcode in order to add product</string>
|
||||
<string name="no_barcode">No barcode present</string>
|
||||
<string name="no_barcode_button">No barcode</string>
|
||||
<string name="register">Register</string>
|
||||
<string name="login">Login</string>
|
||||
<string name="offline">Offline</string>
|
||||
<string name="username">Username</string>
|
||||
<string name="password">Password</string>
|
||||
<string name="username_already_exists">Such account already exists</string>
|
||||
<string name="wrong_password">Wrong password</string>
|
||||
<string name="server">Server</string>
|
||||
<string name="my_account">My account</string>
|
||||
<string name="my_groups">My groups</string>
|
||||
</resources>
|
|
@ -17,15 +17,19 @@ gridlayout = "1.0.0"
|
|||
activity = "1.9.2"
|
||||
legacySupportV4 = "1.0.0"
|
||||
fragment = "1.8.4"
|
||||
okhttp = "4.10.0"
|
||||
playServicesCodeScanner = "16.1.0"
|
||||
securityCrypto = "1.0.0"
|
||||
volley = "1.2.1"
|
||||
zxingAndroidEmbedded = "4.3.0"
|
||||
material3Android = "1.3.0"
|
||||
|
||||
[libraries]
|
||||
androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "cameraView" }
|
||||
androidx-camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "cameraView" }
|
||||
androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "cameraView" }
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
androidx-security-crypto = { module = "androidx.security:security-crypto", version.ref = "securityCrypto" }
|
||||
barcode-scanning = { module = "com.google.mlkit:barcode-scanning", version.ref = "barcodeScanning" }
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||
|
@ -40,9 +44,11 @@ androidx-gridlayout = { group = "androidx.gridlayout", name = "gridlayout", vers
|
|||
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
||||
androidx-legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "legacySupportV4" }
|
||||
androidx-fragment = { group = "androidx.fragment", name = "fragment", version.ref = "fragment" }
|
||||
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
||||
play-services-code-scanner = { module = "com.google.android.gms:play-services-code-scanner", version.ref = "playServicesCodeScanner" }
|
||||
volley = { module = "com.android.volley:volley", version.ref = "volley" }
|
||||
zxing-android-embedded = { module = "com.journeyapps:zxing-android-embedded", version.ref = "zxingAndroidEmbedded" }
|
||||
androidx-material3-android = { group = "androidx.compose.material3", name = "material3-android", version.ref = "material3Android" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
|
|
Loading…
Reference in New Issue