I hope that is first and final commit

This commit is contained in:
SunZar 2024-12-06 22:02:45 +08:00
parent d2a9b7504b
commit a29cdbb5d5
15 changed files with 636 additions and 11 deletions

View File

@ -0,0 +1,6 @@
package ru.myitschool.work.ui;
public class Constants {
public static String KEY_LOGIN = "login";
public static String KEY_RESULT = "result";
}

View File

@ -0,0 +1,20 @@
package ru.myitschool.work.ui;
import com.google.gson.annotations.SerializedName;
public class Door {
@SerializedName("value")
private String code;
public Door(String code) {
this.code = code;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}

View File

@ -0,0 +1,137 @@
package ru.myitschool.work.ui;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentResultListener;
import com.squareup.picasso.Picasso;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import ru.myitschool.work.R;
import ru.myitschool.work.databinding.FragmentInformationBinding;
import ru.myitschool.work.ui.qr.scan.QrScanDestination;
import ru.myitschool.work.ui.qr.scan.QrScanFragment;
public class InformationFragment extends Fragment {
FragmentInformationBinding binding;
SharedPreferences sharedPreferences;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmentInformationBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
sharedPreferences = getContext().getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
getInformation();
binding.refresh.setOnClickListener(view1 -> {
onClickRefresh();
});
binding.scan.setOnClickListener(view1 -> {
onClickScan();
});
binding.logout.setOnClickListener(view2 -> {
onClickLogout();
});
//getParentFragmentManager()
requireActivity().getSupportFragmentManager().setFragmentResultListener(QrScanDestination.REQUEST_KEY, getViewLifecycleOwner(), (requestKey, result) -> {
String res = "";
if (result.get(requestKey) != null) {
res = result.get(requestKey).toString();
}
//Toast.makeText(getContext(), res, Toast.LENGTH_LONG).show();
ResultFragment resFragment = ResultFragment.newInstance(res);
getFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, resFragment).commit();
});
}
private void onClickRefresh() {
getInformation();
}
private void onClickScan() {
getFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new QrScanFragment()).commit();
}
private void onClickLogout() {
sharedPreferences.edit().clear().apply();
getFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new LoginFragment()).commit();
}
private void getInformation() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ru.myitschool.work.core.Constants.SERVER_ADDRESS)
.addConverterFactory(GsonConverterFactory.create())
.build();
StoreAPI storeApi = retrofit.create(StoreAPI.class);
String login = sharedPreferences.getString(Constants.KEY_LOGIN, "");
Call<User> call = storeApi.informationUser(login);
call.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
User user = response.body();
binding.fullname.setText(user.getName());
binding.position.setText(user.getPosition());
binding.lastEntry.setText(user.getLastVisit().substring(0, 10) + " " + user.getLastVisit().substring(11, 16));
Picasso.get().load(user.getPhoto()).into(binding.photo);
} else {
takeError();
}
} else if (response.code() == 401) {
takeError();
} else if (response.code() == 400) {
takeError();
} else {
takeError();
}
}
@Override
public void onFailure(Call<User> call, Throwable t) {
takeError();
}
});
}
private void takeError() {
//binding.photo.setVisibility(View.GONE);
binding.fullname.setVisibility(View.GONE);
binding.lastEntry.setVisibility(View.GONE);
binding.position.setVisibility(View.GONE);
//binding.logout.setVisibility(View.GONE);
binding.scan.setVisibility(View.GONE);
binding.error.setVisibility(View.VISIBLE);
}
}

View File

@ -0,0 +1,121 @@
package ru.myitschool.work.ui;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import ru.myitschool.work.R;
import ru.myitschool.work.core.Constants;
import ru.myitschool.work.databinding.FragmentLoginBinding;
public class LoginFragment extends Fragment {
FragmentLoginBinding binding;
SharedPreferences sharedPreferences;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmentLoginBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//binding.log.setText("created");
sharedPreferences = getContext().getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
//sharedPreferences.edit().putString(ru.myitschool.work.ui.Constants.KEY_LOGIN, "5user").apply();
binding.login.setEnabled(false);
binding.username.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (binding.username.getText().length() >= 3 && binding.username.getText().toString().matches("[0-9a-zA-Z]+") && (binding.username.getText().toString().charAt(0) + "").matches("[0-9]+")) {
binding.login.setEnabled(true);
//binding.log.setText("changed true");
} else {
binding.login.setEnabled(false);
//binding.log.setText("changed false");
}
//Log.d("tagg", "changed");
if (binding.error.getVisibility() == View.VISIBLE) {
binding.error.setVisibility(View.GONE);
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
binding.login.setOnClickListener(view1 -> {
if (binding.login.isEnabled()) {
if (binding.error.getVisibility() == View.VISIBLE) {
binding.error.setVisibility(View.GONE);
//binding.log.setText("click enabled");
}
//binding.log.setText("click");
onClickLogin();
}
});
}
private void onClickLogin() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.SERVER_ADDRESS)
.addConverterFactory(GsonConverterFactory.create())
.build();
StoreAPI storeApi = retrofit.create(StoreAPI.class);
String login = binding.username.getText().toString();
Call<Boolean> call = storeApi.authenticateUser(login);
call.enqueue(new Callback<Boolean>() {
@Override
public void onResponse(Call<Boolean> call, Response<Boolean> response) {
if (response.isSuccessful()) {
if (response.body() != null && response.body()) {
sharedPreferences.edit().putString(ru.myitschool.work.ui.Constants.KEY_LOGIN, binding.username.getText().toString()).apply();
getFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new InformationFragment()).commit();
} else {
binding.error.setVisibility(View.VISIBLE);
}
} else if (response.code() == 401) {
binding.error.setVisibility(View.VISIBLE);
} else if (response.code() == 400) {
binding.error.setVisibility(View.VISIBLE);
} else {
binding.error.setVisibility(View.VISIBLE);
}
}
@Override
public void onFailure(Call<Boolean> call, Throwable t) {
binding.error.setVisibility(View.VISIBLE);
}
});
}
}

View File

@ -0,0 +1,100 @@
package ru.myitschool.work.ui;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import ru.myitschool.work.R;
import ru.myitschool.work.databinding.FragmentResultBinding;
public class ResultFragment extends Fragment {
FragmentResultBinding binding;
SharedPreferences sharedPreferences;
Door door;
public static ResultFragment newInstance(String data) {
ResultFragment fragment = new ResultFragment();
Bundle args = new Bundle();
args.putString(Constants.KEY_RESULT, data);
fragment.setArguments(args);
return fragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmentResultBinding.inflate(inflater, container, false);
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
sharedPreferences = getContext().getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
if (getArguments() != null) {
door = new Door(getArguments().getString(Constants.KEY_RESULT, ""));
} else {
door = new Door("");
}
if (Objects.equals(door.getCode(), "")) {
binding.result.setText(getText(R.string.cancelled));
} else {
patchDoor();
}
binding.close.setOnClickListener(view1 -> {
onClickClose();
});
}
private void onClickClose() {
getFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new InformationFragment()).commit();
}
private void patchDoor() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ru.myitschool.work.core.Constants.SERVER_ADDRESS)
.addConverterFactory(GsonConverterFactory.create())
.build();
StoreAPI storeApi = retrofit.create(StoreAPI.class);
String login = sharedPreferences.getString(Constants.KEY_LOGIN, "");
Call<Void> call = storeApi.openDoor(login, door);
call.enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) {
if (response.isSuccessful()) {
binding.result.setText(getText(R.string.success));
} else if (response.code() == 401) {
binding.result.setText(getText(R.string.wrong));
} else if (response.code() == 400) {
binding.result.setText(getText(R.string.wrong));
} else {
binding.result.setText(getText(R.string.wrong));
}
}
@Override
public void onFailure(Call<Void> call, Throwable t) {
binding.result.setText(getText(R.string.wrong));
}
});
}
}

View File

@ -1,6 +1,9 @@
package ru.myitschool.work.ui
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.createGraph
@ -31,17 +34,41 @@ class RootActivity : AppCompatActivity() {
) {
fragment<LoginFragment, LoginDestination>()
fragment<QrScanFragment, QrScanDestination>()
fragment<ru.myitschool.work.ui.LoginFragment, LoginDestination>()
fragment<ResultFragment, LoginDestination>()
}
}
onBackPressedDispatcher.addCallback(
val sharedPreferences = getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE)
val login = sharedPreferences.getString(Constants.KEY_LOGIN, "")
//Toast.makeText(baseContext, login, Toast.LENGTH_LONG).show()
if (login != "") {
val fragment = ru.myitschool.work.ui.InformationFragment() // Create an instance of your fragment
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.nav_host_fragment, fragment) // Add the fragment to the container
transaction.commit()
} else {
val fragment = ru.myitschool.work.ui.LoginFragment() // Create an instance of your fragment
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.nav_host_fragment, fragment) // Add the fragment to the container
transaction.commit()
}
/*if (supportFragmentManager.findFragmentById(R.id.nav_host_fragment) == null) {
Toast.makeText(baseContext, "hhgjgg", Toast.LENGTH_LONG).show()
val fragment = ru.myitschool.work.ui.LoginFragment() // Create an instance of your fragment
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.nav_host_fragment, fragment) // Add the fragment to the container
transaction.commit()
}*/
/*onBackPressedDispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
onSupportNavigateUp()
}
}
)
)*/
}
override fun onSupportNavigateUp(): Boolean {

View File

@ -0,0 +1,19 @@
package ru.myitschool.work.ui;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.PATCH;
import retrofit2.http.Path;
public interface StoreAPI {
@GET("api/{login}/auth")
Call<Boolean> authenticateUser(@Path("login") String login);
@GET("api/{login}/info")
Call<User> informationUser(@Path("login") String login);
@PATCH("api/{login}/open")
Call<Void> openDoor(@Path("login") String login, @Body Door request);
}

View File

@ -0,0 +1,68 @@
package ru.myitschool.work.ui;
public class User {
private int id;
private String login;
private String name;
private String photo;
private String position;
private String lastVisit;
public User(int id, String login, String name, String photo, String position, String lastVisit) {
this.id = id;
this.login = login;
this.name = name;
this.photo = photo;
this.position = position;
this.lastVisit = lastVisit;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public String getLastVisit() {
return lastVisit;
}
public void setLastVisit(String lastVisit) {
this.lastVisit = lastVisit;
}
}

View File

@ -1,6 +1,8 @@
package ru.myitschool.work.ui.login
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
@ -23,7 +25,6 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
subscribe()
}
private fun subscribe() {
viewModel.state.collectWhenStarted(this) { state ->
binding.loading.visibleOrGone(state)

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/fullname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/lastEntry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/logout"
android:text="@string/logout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/refresh"
android:text="@string/refresh"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/scan"
android:text="@string/scan"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/error"
android:visibility="gone"
android:text="@string/error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

View File

@ -1,16 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/username"/>
<Button
android:id="@+id/login"
android:text="@string/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/error"
android:visibility="gone"
android:text="@string/error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ProgressBar
android:id="@+id/loading"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
android:layout_height="wrap_content" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/close"
android:text="@string/close"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

View File

@ -0,0 +1,14 @@
<resources>
<string name="app_name">NTO Pass</string>
<string name="username">Login</string>
<string name="close">Close</string>
<string name="login">Login</string>
<string name="logout">Logout</string>
<string name="refresh">Refresh</string>
<string name="scan">Scan</string>
<string name="error">Error</string>
<string name="cancelled">Operation was cancelled</string>
<string name="success">Success</string>
<string name="wrong">Something wrong</string>
</resources>

View File

@ -0,0 +1,14 @@
<resources>
<string name="app_name">NTO Pass</string>
<string name="username">Логин</string>
<string name="close">Закрыть</string>
<string name="login">Войти</string>
<string name="logout">Выйти</string>
<string name="refresh">Обновить</string>
<string name="scan">Отсканировать</string>
<string name="error">Ошибка</string>
<string name="cancelled">Вход был отменён</string>
<string name="success">Успешно</string>
<string name="wrong">Что-то пошло не так</string>
</resources>

View File

@ -1,3 +1,14 @@
<resources>
<string name="app_name">NTO Pass</string>
<string name="username">Логин</string>
<string name="close">Закрыть</string>
<string name="login">Войти</string>
<string name="logout">Выйти</string>
<string name="refresh">Обновить</string>
<string name="scan">Отсканировать</string>
<string name="error">Ошибка</string>
<string name="cancelled">Вход был отменён</string>
<string name="success">Успешно</string>
<string name="wrong">Что-то пошло не так</string>
</resources>