mirror of
https://github.com/antebudimir/tempus.git
synced 2026-01-03 02:41:40 +00:00
Multi server/user implementation
This commit is contained in:
parent
4e269a7446
commit
78a4006ed6
30 changed files with 959 additions and 192 deletions
|
|
@ -179,8 +179,11 @@ public class MainActivity extends BaseActivity {
|
|||
|
||||
// NAVIGATION
|
||||
public void goToLogin() {
|
||||
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.landingFragment)
|
||||
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.landingFragment) {
|
||||
navController.navigate(R.id.action_landingFragment_to_loginFragment);
|
||||
} else if(Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.settingsFragment) {
|
||||
navController.navigate(R.id.action_settingsFragment_to_loginFragment);
|
||||
}
|
||||
}
|
||||
|
||||
public void goToHome() {
|
||||
|
|
|
|||
|
|
@ -1,44 +1,64 @@
|
|||
package com.cappielloantonio.play.ui.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.cappielloantonio.play.App;
|
||||
import com.cappielloantonio.play.R;
|
||||
import com.cappielloantonio.play.adapter.ServerAdapter;
|
||||
import com.cappielloantonio.play.databinding.FragmentLoginBinding;
|
||||
import com.cappielloantonio.play.interfaces.SystemCallback;
|
||||
import com.cappielloantonio.play.repository.SystemRepository;
|
||||
import com.cappielloantonio.play.service.MusicPlayerRemote;
|
||||
import com.cappielloantonio.play.ui.activity.MainActivity;
|
||||
import com.cappielloantonio.play.util.PreferenceUtil;
|
||||
import com.cappielloantonio.play.ui.fragment.dialog.ServerSignupDialog;
|
||||
import com.cappielloantonio.play.viewmodel.LoginViewModel;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class LoginFragment extends Fragment {
|
||||
private static final String TAG = "LoginFragment";
|
||||
|
||||
private FragmentLoginBinding bind;
|
||||
private MainActivity activity;
|
||||
private LoginViewModel loginViewModel;
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
private String server;
|
||||
private ServerAdapter serverAdapter;
|
||||
|
||||
private SystemRepository systemRepository;
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
inflater.inflate(R.menu.login_page_menu, menu);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
activity = (MainActivity) getActivity();
|
||||
|
||||
loginViewModel = new ViewModelProvider(requireActivity()).get(LoginViewModel.class);
|
||||
bind = FragmentLoginBinding.inflate(inflater, container, false);
|
||||
View view = bind.getRoot();
|
||||
init();
|
||||
|
||||
initAppBar();
|
||||
initServerListView();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
|
@ -49,67 +69,75 @@ public class LoginFragment extends Fragment {
|
|||
bind = null;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
systemRepository = new SystemRepository(App.getInstance());
|
||||
private void initAppBar() {
|
||||
activity.setSupportActionBar(bind.toolbar);
|
||||
|
||||
bind.loginButton.setOnClickListener(v -> {
|
||||
if (validateInput()) {
|
||||
saveServerPreference(server, username, password, null, null);
|
||||
authenticate();
|
||||
bind.appBarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> {
|
||||
if ((bind.serverInfoSector.getHeight() + verticalOffset) < (2 * ViewCompat.getMinimumHeight(bind.toolbar))) {
|
||||
bind.toolbar.setTitle("Subsonic servers");
|
||||
} else {
|
||||
bind.toolbar.setTitle("");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean validateInput() {
|
||||
username = bind.usernameTextView.getText().toString().trim();
|
||||
password = bind.passwordTextView.getText().toString();
|
||||
server = bind.serverTextView.getText().toString().trim();
|
||||
private void initServerListView() {
|
||||
bind.serverListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
bind.serverListRecyclerView.setHasFixedSize(true);
|
||||
|
||||
if (TextUtils.isEmpty(username)) {
|
||||
Toast.makeText(requireContext(), "Empty username", Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(server)) {
|
||||
Toast.makeText(requireContext(), "Empty server url", Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void authenticate() {
|
||||
systemRepository.checkUserCredential(new SystemCallback() {
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
Log.e(TAG, exception.getMessage());
|
||||
Toast.makeText(requireContext(), exception.getMessage(), Toast.LENGTH_LONG).show();
|
||||
serverAdapter = new ServerAdapter(activity, requireContext());
|
||||
bind.serverListRecyclerView.setAdapter(serverAdapter);
|
||||
loginViewModel.getServerList().observe(requireActivity(), servers -> {
|
||||
if(servers.size() > 0) {
|
||||
if (bind != null) bind.noServerAddedTextView.setVisibility(View.GONE);
|
||||
if (bind != null) bind.serverListRecyclerView.setVisibility(View.VISIBLE);
|
||||
serverAdapter.setItems(servers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(String token, String salt) {
|
||||
saveServerPreference(null, null, null, token, salt);
|
||||
enter();
|
||||
else {
|
||||
if (bind != null) bind.noServerAddedTextView.setVisibility(View.VISIBLE);
|
||||
if (bind != null) bind.serverListRecyclerView.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT) {
|
||||
int originalPosition = -1;
|
||||
int fromPosition = -1;
|
||||
int toPosition = -1;
|
||||
|
||||
@Override
|
||||
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
|
||||
if (originalPosition == -1)
|
||||
originalPosition = viewHolder.getBindingAdapterPosition();
|
||||
|
||||
fromPosition = viewHolder.getBindingAdapterPosition();
|
||||
toPosition = target.getBindingAdapterPosition();
|
||||
|
||||
Collections.swap(serverAdapter.getItems(), fromPosition, toPosition);
|
||||
recyclerView.getAdapter().notifyItemMoved(fromPosition, toPosition);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
|
||||
loginViewModel.deleteServer(serverAdapter.getItem(viewHolder.getBindingAdapterPosition()));
|
||||
bind.serverListRecyclerView.getAdapter().notifyItemRemoved(viewHolder.getBindingAdapterPosition());
|
||||
}
|
||||
}
|
||||
).attachToRecyclerView(bind.serverListRecyclerView);
|
||||
}
|
||||
|
||||
private void enter() {
|
||||
activity.goFromLogin();
|
||||
}
|
||||
|
||||
private void saveServerPreference(String server, String user, String password, String token, String salt) {
|
||||
if (user != null) PreferenceUtil.getInstance(requireContext()).setUser(user);
|
||||
if (server != null) PreferenceUtil.getInstance(requireContext()).setServer(server);
|
||||
if (password != null) PreferenceUtil.getInstance(requireContext()).setPassword(password);
|
||||
|
||||
if (token != null && salt != null) {
|
||||
PreferenceUtil.getInstance(requireContext()).setPassword(null);
|
||||
PreferenceUtil.getInstance(requireContext()).setToken(token);
|
||||
PreferenceUtil.getInstance(requireContext()).setSalt(salt);
|
||||
return;
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_add:
|
||||
ServerSignupDialog dialog = new ServerSignupDialog();
|
||||
dialog.show(activity.getSupportFragmentManager(), null);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
App.getSubsonicClientInstance(requireContext(), true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
|
||||
import com.cappielloantonio.play.R;
|
||||
import com.cappielloantonio.play.helper.ThemeHelper;
|
||||
import com.cappielloantonio.play.ui.activity.MainActivity;
|
||||
import com.cappielloantonio.play.util.PreferenceUtil;
|
||||
|
||||
public class SettingsFragment extends PreferenceFragmentCompat {
|
||||
private static final String TAG = "SettingsFragment";
|
||||
|
|
@ -36,6 +38,24 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
|||
activity.setBottomNavigationBarVisibility(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
findPreference("logout").setOnPreferenceClickListener(preference -> {
|
||||
PreferenceUtil.getInstance(requireContext()).setUser(null);
|
||||
PreferenceUtil.getInstance(requireContext()).setServer(null);
|
||||
PreferenceUtil.getInstance(requireContext()).setPassword(null);
|
||||
PreferenceUtil.getInstance(requireContext()).setToken(null);
|
||||
PreferenceUtil.getInstance(requireContext()).setSalt(null);
|
||||
PreferenceUtil.getInstance(requireContext()).setServerId(null);
|
||||
|
||||
activity.goToLogin();
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
setPreferencesFromResource(R.xml.global_preferences, rootKey);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
package com.cappielloantonio.play.ui.fragment.dialog;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.cappielloantonio.play.App;
|
||||
import com.cappielloantonio.play.R;
|
||||
import com.cappielloantonio.play.databinding.DialogServerSignupBinding;
|
||||
import com.cappielloantonio.play.interfaces.SystemCallback;
|
||||
import com.cappielloantonio.play.model.Server;
|
||||
import com.cappielloantonio.play.repository.SystemRepository;
|
||||
import com.cappielloantonio.play.ui.activity.MainActivity;
|
||||
import com.cappielloantonio.play.util.PreferenceUtil;
|
||||
import com.cappielloantonio.play.viewmodel.LoginViewModel;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ServerSignupDialog extends DialogFragment {
|
||||
private static final String TAG = "ServerSignupDialog";
|
||||
|
||||
private DialogServerSignupBinding bind;
|
||||
private MainActivity activity;
|
||||
private Context context;
|
||||
private LoginViewModel loginViewModel;
|
||||
|
||||
private SystemRepository systemRepository;
|
||||
|
||||
private String serverName;
|
||||
private String username;
|
||||
private String password;
|
||||
private String server;
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
activity = (MainActivity) getActivity();
|
||||
context = requireContext();
|
||||
|
||||
loginViewModel = new ViewModelProvider(requireActivity()).get(LoginViewModel.class);
|
||||
systemRepository = new SystemRepository(App.getInstance());
|
||||
|
||||
bind = DialogServerSignupBinding.inflate(LayoutInflater.from(requireContext()));
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
|
||||
builder.setView(bind.getRoot())
|
||||
.setTitle("Add server")
|
||||
.setPositiveButton("Enter", (dialog, id) -> { })
|
||||
.setNegativeButton("Cancel", (dialog, id) -> dialog.cancel());
|
||||
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getResources().getColor(R.color.colorAccent, null));
|
||||
((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getResources().getColor(R.color.colorAccent, null));
|
||||
|
||||
((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
|
||||
if (validateInput()) {
|
||||
saveServerPreference(server, username, password, null, null);
|
||||
authenticate();
|
||||
((AlertDialog) Objects.requireNonNull(getDialog())).dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean validateInput() {
|
||||
serverName = bind.serverNameTextView.getText().toString().trim();
|
||||
username = bind.usernameTextView.getText().toString().trim();
|
||||
password = bind.passwordTextView.getText().toString();
|
||||
server = bind.serverTextView.getText().toString().trim();
|
||||
|
||||
if (TextUtils.isEmpty(serverName)) {
|
||||
bind.serverNameTextView.setError("Required");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(username)) {
|
||||
bind.usernameTextView.setError("Required");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(server)) {
|
||||
bind.serverTextView.setError("Required");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void authenticate() {
|
||||
systemRepository.checkUserCredential(new SystemCallback() {
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
Log.e(TAG, exception.getMessage());
|
||||
Toast.makeText(requireContext(), exception.getMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(String token, String salt) {
|
||||
saveServerPreference(null, null, null, token, salt);
|
||||
enter();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void enter() {
|
||||
activity.goFromLogin();
|
||||
}
|
||||
|
||||
private void saveServerPreference(String server, String user, String password, String token, String salt) {
|
||||
if (user != null) PreferenceUtil.getInstance(context).setUser(user);
|
||||
if (server != null) PreferenceUtil.getInstance(context).setServer(server);
|
||||
if (password != null) PreferenceUtil.getInstance(context).setPassword(password);
|
||||
|
||||
if (token != null && salt != null) {
|
||||
String serverID = UUID.randomUUID().toString();
|
||||
|
||||
PreferenceUtil.getInstance(context).setPassword(null);
|
||||
PreferenceUtil.getInstance(context).setToken(token);
|
||||
PreferenceUtil.getInstance(context).setSalt(salt);
|
||||
PreferenceUtil.getInstance(context).setServerId(serverID);
|
||||
|
||||
loginViewModel.addServer(new Server(serverID, this.serverName, this.username, this.server, token, salt, System.currentTimeMillis()));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
App.getSubsonicClientInstance(requireContext(), true);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue