Replace Butterknife code with ViewBinding

This commit is contained in:
Niko Diamadis
2022-10-11 22:20:41 +02:00
parent fb3958acf1
commit ad809d149c
10 changed files with 180 additions and 216 deletions

View File

@@ -27,6 +27,9 @@ android {
resValue "string", "app_name", "Gotify DEV" resValue "string", "app_name", "Gotify DEV"
} }
} }
buildFeatures {
viewBinding true
}
compileOptions { compileOptions {
sourceCompatibility = '1.8' sourceCompatibility = '1.8'
targetCompatibility = '1.8' targetCompatibility = '1.8'

View File

@@ -13,18 +13,21 @@ import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import com.github.gotify.R; import com.github.gotify.R;
import com.github.gotify.Utils; import com.github.gotify.Utils;
import com.github.gotify.databinding.ActivityLogsBinding;
public class LogsActivity extends AppCompatActivity { public class LogsActivity extends AppCompatActivity {
private ActivityLogsBinding binding;
private Handler handler = new Handler(); private Handler handler = new Handler();
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logs); binding = ActivityLogsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
Log.i("Entering " + getClass().getSimpleName()); Log.i("Entering " + getClass().getSimpleName());
updateLogs(); updateLogs();
setSupportActionBar(findViewById(R.id.toolbar)); setSupportActionBar(binding.appBarDrawer.toolbar);
ActionBar actionBar = getSupportActionBar(); ActionBar actionBar = getSupportActionBar();
if (actionBar != null) { if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true);
@@ -54,7 +57,7 @@ public class LogsActivity extends AppCompatActivity {
Log.clear(); Log.clear();
} }
if (item.getItemId() == R.id.action_copy_logs) { if (item.getItemId() == R.id.action_copy_logs) {
TextView content = findViewById(R.id.log_content); TextView content = binding.logContent;
ClipboardManager clipboardManager = ClipboardManager clipboardManager =
(ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = ClipData.newPlainText("GotifyLog", content.getText().toString()); ClipData clipData = ClipData.newPlainText("GotifyLog", content.getText().toString());
@@ -73,7 +76,7 @@ public class LogsActivity extends AppCompatActivity {
@Override @Override
protected void onPostExecute(String s) { protected void onPostExecute(String s) {
TextView content = findViewById(R.id.log_content); TextView content = binding.logContent;
if (content.getSelectionStart() == content.getSelectionEnd()) { if (content.getSelectionStart() == content.getSelectionEnd()) {
content.setText(s); content.setText(s);
} }

View File

@@ -3,26 +3,23 @@ package com.github.gotify.login;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.TextView;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.github.gotify.R; import com.github.gotify.R;
import com.github.gotify.databinding.AdvancedSettingsDialogBinding;
class AdvancedDialog { class AdvancedDialog {
private Context context; private Context context;
private ViewHolder holder; private LayoutInflater layoutInflater;
private AdvancedSettingsDialogBinding binding;
private CompoundButton.OnCheckedChangeListener onCheckedChangeListener; private CompoundButton.OnCheckedChangeListener onCheckedChangeListener;
private Runnable onClickSelectCaCertificate; private Runnable onClickSelectCaCertificate;
private Runnable onClickRemoveCaCertificate; private Runnable onClickRemoveCaCertificate;
AdvancedDialog(Context context) { AdvancedDialog(Context context, LayoutInflater layoutInflater) {
this.context = context; this.context = context;
this.layoutInflater = layoutInflater;
} }
AdvancedDialog onDisableSSLChanged( AdvancedDialog onDisableSSLChanged(
@@ -42,12 +39,9 @@ class AdvancedDialog {
} }
AdvancedDialog show(boolean disableSSL, @Nullable String selectedCertificate) { AdvancedDialog show(boolean disableSSL, @Nullable String selectedCertificate) {
binding = AdvancedSettingsDialogBinding.inflate(layoutInflater);
View dialogView = binding.disableSSL.setChecked(disableSSL);
LayoutInflater.from(context).inflate(R.layout.advanced_settings_dialog, null); binding.disableSSL.setOnCheckedChangeListener(onCheckedChangeListener);
holder = new ViewHolder(dialogView);
holder.disableSSL.setChecked(disableSSL);
holder.disableSSL.setOnCheckedChangeListener(onCheckedChangeListener);
if (selectedCertificate == null) { if (selectedCertificate == null) {
showSelectCACertificate(); showSelectCACertificate();
@@ -56,7 +50,7 @@ class AdvancedDialog {
} }
new AlertDialog.Builder(context) new AlertDialog.Builder(context)
.setView(dialogView) .setView(binding.getRoot())
.setTitle(R.string.advanced_settings) .setTitle(R.string.advanced_settings)
.setPositiveButton(context.getString(R.string.done), (ignored, ignored2) -> {}) .setPositiveButton(context.getString(R.string.done), (ignored, ignored2) -> {})
.show(); .show();
@@ -64,33 +58,18 @@ class AdvancedDialog {
} }
private void showSelectCACertificate() { private void showSelectCACertificate() {
holder.toggleCaCert.setText(R.string.select_ca_certificate); binding.toggleCaCert.setText(R.string.select_ca_certificate);
holder.toggleCaCert.setOnClickListener((a) -> onClickSelectCaCertificate.run()); binding.toggleCaCert.setOnClickListener((a) -> onClickSelectCaCertificate.run());
holder.selectedCaCertificate.setText(R.string.no_certificate_selected); binding.selecetedCaCert.setText(R.string.no_certificate_selected);
} }
void showRemoveCACertificate(String certificate) { void showRemoveCACertificate(String certificate) {
holder.toggleCaCert.setText(R.string.remove_ca_certificate); binding.toggleCaCert.setText(R.string.remove_ca_certificate);
holder.toggleCaCert.setOnClickListener( binding.toggleCaCert.setOnClickListener(
(a) -> { (a) -> {
showSelectCACertificate(); showSelectCACertificate();
onClickRemoveCaCertificate.run(); onClickRemoveCaCertificate.run();
}); });
holder.selectedCaCertificate.setText(certificate); binding.selecetedCaCert.setText(certificate);
}
class ViewHolder {
@BindView(R.id.disableSSL)
CheckBox disableSSL;
@BindView(R.id.toggle_ca_cert)
Button toggleCaCert;
@BindView(R.id.seleceted_ca_cert)
TextView selectedCaCertificate;
ViewHolder(View view) {
ButterKnife.bind(this, view);
}
} }
} }

View File

@@ -6,19 +6,14 @@ import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View; import android.view.View;
import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ContextThemeWrapper; import androidx.appcompat.view.ContextThemeWrapper;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnTextChanged;
import com.github.gotify.R; import com.github.gotify.R;
import com.github.gotify.SSLSettings; import com.github.gotify.SSLSettings;
import com.github.gotify.Settings; import com.github.gotify.Settings;
@@ -32,6 +27,7 @@ import com.github.gotify.client.api.ClientApi;
import com.github.gotify.client.api.UserApi; import com.github.gotify.client.api.UserApi;
import com.github.gotify.client.model.Client; import com.github.gotify.client.model.Client;
import com.github.gotify.client.model.VersionInfo; import com.github.gotify.client.model.VersionInfo;
import com.github.gotify.databinding.ActivityLoginBinding;
import com.github.gotify.init.InitializationActivity; import com.github.gotify.init.InitializationActivity;
import com.github.gotify.log.Log; import com.github.gotify.log.Log;
import com.github.gotify.log.LogsActivity; import com.github.gotify.log.LogsActivity;
@@ -48,30 +44,7 @@ public class LoginActivity extends AppCompatActivity {
// return value from startActivityForResult when choosing a certificate // return value from startActivityForResult when choosing a certificate
private final int FILE_SELECT_CODE = 1; private final int FILE_SELECT_CODE = 1;
@BindView(R.id.username) private ActivityLoginBinding binding;
EditText usernameField;
@BindView(R.id.gotify_url)
EditText urlField;
@BindView(R.id.password)
EditText passwordField;
@BindView(R.id.advanced_settings)
ImageView toggleAdvanced;
@BindView(R.id.checkurl)
Button checkUrlButton;
@BindView(R.id.login)
Button loginButton;
@BindView(R.id.checkurl_progress)
ProgressBar checkUrlProgress;
@BindView(R.id.login_progress)
ProgressBar loginProgress;
private Settings settings; private Settings settings;
private boolean disableSSLValidation; private boolean disableSSLValidation;
@@ -82,27 +55,46 @@ public class LoginActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
UncaughtExceptionHandler.registerCurrentThread(); UncaughtExceptionHandler.registerCurrentThread();
setContentView(R.layout.activity_login); binding = ActivityLoginBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
Log.i("Entering " + getClass().getSimpleName()); Log.i("Entering " + getClass().getSimpleName());
ButterKnife.bind(this);
settings = new Settings(this); settings = new Settings(this);
} }
@OnTextChanged(R.id.gotify_url) @Override
public void onUrlChange() { protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
binding.gotifyUrl.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) {
invalidateUrl(); invalidateUrl();
} }
private void invalidateUrl() { @Override
usernameField.setVisibility(View.GONE); public void afterTextChanged(Editable editable) {}
passwordField.setVisibility(View.GONE); });
loginButton.setVisibility(View.GONE);
checkUrlButton.setText(getString(R.string.check_url)); binding.checkurl.setOnClickListener(ignored -> doCheckUrl());
binding.openLogs.setOnClickListener(ignored -> openLogs());
binding.advancedSettings.setOnClickListener(ignored -> toggleShowAdvanced());
binding.login.setOnClickListener(ignored -> doLogin());
}
private void invalidateUrl() {
binding.username.setVisibility(View.GONE);
binding.password.setVisibility(View.GONE);
binding.login.setVisibility(View.GONE);
binding.checkurl.setText(getString(R.string.check_url));
} }
@OnClick(R.id.checkurl)
public void doCheckUrl() { public void doCheckUrl() {
String url = urlField.getText().toString(); String url = binding.gotifyUrl.getText().toString();
HttpUrl parsedUrl = HttpUrl.parse(url); HttpUrl parsedUrl = HttpUrl.parse(url);
if (parsedUrl == null) { if (parsedUrl == null) {
Utils.showSnackBar(LoginActivity.this, "Invalid URL (include http:// or https://)"); Utils.showSnackBar(LoginActivity.this, "Invalid URL (include http:// or https://)");
@@ -113,8 +105,8 @@ public class LoginActivity extends AppCompatActivity {
showHttpWarning(); showHttpWarning();
} }
checkUrlProgress.setVisibility(View.VISIBLE); binding.checkurlProgress.setVisibility(View.VISIBLE);
checkUrlButton.setVisibility(View.GONE); binding.checkurl.setVisibility(View.GONE);
final String trimmedUrl = url.trim(); final String trimmedUrl = url.trim();
final String fixedUrl = final String fixedUrl =
@@ -127,8 +119,8 @@ public class LoginActivity extends AppCompatActivity {
.getVersion() .getVersion()
.enqueue(callInUI(this, onValidUrl(fixedUrl), onInvalidUrl(fixedUrl))); .enqueue(callInUI(this, onValidUrl(fixedUrl), onInvalidUrl(fixedUrl)));
} catch (Exception e) { } catch (Exception e) {
checkUrlProgress.setVisibility(View.GONE); binding.checkurlProgress.setVisibility(View.GONE);
checkUrlButton.setVisibility(View.VISIBLE); binding.checkurl.setVisibility(View.VISIBLE);
String errorMsg = String errorMsg =
getString(R.string.version_failed, fixedUrl + "/version", e.getMessage()); getString(R.string.version_failed, fixedUrl + "/version", e.getMessage());
Utils.showSnackBar(LoginActivity.this, errorMsg); Utils.showSnackBar(LoginActivity.this, errorMsg);
@@ -144,18 +136,16 @@ public class LoginActivity extends AppCompatActivity {
.show(); .show();
} }
@OnClick(R.id.open_logs)
public void openLogs() { public void openLogs() {
startActivity(new Intent(this, LogsActivity.class)); startActivity(new Intent(this, LogsActivity.class));
} }
@OnClick(R.id.advanced_settings)
void toggleShowAdvanced() { void toggleShowAdvanced() {
String selectedCertName = String selectedCertName =
caCertContents != null ? getNameOfCertContent(caCertContents) : null; caCertContents != null ? getNameOfCertContent(caCertContents) : null;
advancedDialog = advancedDialog =
new AdvancedDialog(this) new AdvancedDialog(this, getLayoutInflater())
.onDisableSSLChanged( .onDisableSSLChanged(
(ignored, disable) -> { (ignored, disable) -> {
invalidateUrl(); invalidateUrl();
@@ -231,31 +221,31 @@ public class LoginActivity extends AppCompatActivity {
private Callback.SuccessCallback<VersionInfo> onValidUrl(String url) { private Callback.SuccessCallback<VersionInfo> onValidUrl(String url) {
return (version) -> { return (version) -> {
settings.url(url); settings.url(url);
checkUrlProgress.setVisibility(View.GONE); binding.checkurlProgress.setVisibility(View.GONE);
checkUrlButton.setVisibility(View.VISIBLE); binding.checkurl.setVisibility(View.VISIBLE);
checkUrlButton.setText(getString(R.string.found_gotify_version, version.getVersion())); binding.checkurl.setText(
usernameField.setVisibility(View.VISIBLE); getString(R.string.found_gotify_version, version.getVersion()));
usernameField.requestFocus(); binding.username.setVisibility(View.VISIBLE);
passwordField.setVisibility(View.VISIBLE); binding.username.requestFocus();
loginButton.setVisibility(View.VISIBLE); binding.password.setVisibility(View.VISIBLE);
binding.login.setVisibility(View.VISIBLE);
}; };
} }
private Callback.ErrorCallback onInvalidUrl(String url) { private Callback.ErrorCallback onInvalidUrl(String url) {
return (exception) -> { return (exception) -> {
checkUrlProgress.setVisibility(View.GONE); binding.checkurlProgress.setVisibility(View.GONE);
checkUrlButton.setVisibility(View.VISIBLE); binding.checkurl.setVisibility(View.VISIBLE);
Utils.showSnackBar(LoginActivity.this, versionError(url, exception)); Utils.showSnackBar(LoginActivity.this, versionError(url, exception));
}; };
} }
@OnClick(R.id.login)
public void doLogin() { public void doLogin() {
String username = usernameField.getText().toString(); String username = binding.username.getText().toString();
String password = passwordField.getText().toString(); String password = binding.password.getText().toString();
loginButton.setVisibility(View.GONE); binding.login.setVisibility(View.GONE);
loginProgress.setVisibility(View.VISIBLE); binding.loginProgress.setVisibility(View.VISIBLE);
ApiClient client = ApiClient client =
ClientFactory.basicAuth(settings.url(), tempSSLSettings(), username, password); ClientFactory.basicAuth(settings.url(), tempSSLSettings(), username, password);
@@ -265,8 +255,8 @@ public class LoginActivity extends AppCompatActivity {
} }
private void onInvalidLogin(ApiException e) { private void onInvalidLogin(ApiException e) {
loginButton.setVisibility(View.VISIBLE); binding.login.setVisibility(View.VISIBLE);
loginProgress.setVisibility(View.GONE); binding.loginProgress.setVisibility(View.GONE);
Utils.showSnackBar(this, getString(R.string.wronguserpw)); Utils.showSnackBar(this, getString(R.string.wronguserpw));
} }
@@ -304,13 +294,13 @@ public class LoginActivity extends AppCompatActivity {
private void onFailedToCreateClient(ApiException e) { private void onFailedToCreateClient(ApiException e) {
Utils.showSnackBar(this, getString(R.string.create_client_failed)); Utils.showSnackBar(this, getString(R.string.create_client_failed));
loginProgress.setVisibility(View.GONE); binding.loginProgress.setVisibility(View.GONE);
loginButton.setVisibility(View.VISIBLE); binding.login.setVisibility(View.VISIBLE);
} }
private void onCancelClientDialog(DialogInterface dialog, int which) { private void onCancelClientDialog(DialogInterface dialog, int which) {
loginProgress.setVisibility(View.GONE); binding.loginProgress.setVisibility(View.GONE);
loginButton.setVisibility(View.VISIBLE); binding.login.setVisibility(View.VISIBLE);
} }
private String versionError(String url, ApiException exception) { private String versionError(String url, ApiException exception) {

View File

@@ -7,7 +7,6 @@ import android.content.SharedPreferences;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.text.util.Linkify; import android.text.util.Linkify;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
@@ -16,13 +15,14 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView; import androidx.viewbinding.ViewBinding;
import butterknife.ButterKnife;
import com.github.gotify.MarkwonFactory; import com.github.gotify.MarkwonFactory;
import com.github.gotify.R; import com.github.gotify.R;
import com.github.gotify.Settings; import com.github.gotify.Settings;
import com.github.gotify.Utils; import com.github.gotify.Utils;
import com.github.gotify.client.model.Message; import com.github.gotify.client.model.Message;
import com.github.gotify.databinding.MessageItemBinding;
import com.github.gotify.databinding.MessageItemCompactBinding;
import com.github.gotify.messages.provider.MessageWithImage; import com.github.gotify.messages.provider.MessageWithImage;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import io.noties.markwon.Markwon; import io.noties.markwon.Markwon;
@@ -90,9 +90,17 @@ public class ListMessageAdapter extends RecyclerView.Adapter<ListMessageAdapter.
@NonNull @NonNull
@Override @Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(messageLayout, parent, false); ViewHolder holder;
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
if (messageLayout == R.layout.message_item) {
MessageItemBinding binding = MessageItemBinding.inflate(layoutInflater, parent, false);
holder = new ViewHolder(binding);
} else {
MessageItemCompactBinding binding =
MessageItemCompactBinding.inflate(layoutInflater, parent, false);
holder = new ViewHolder(binding);
}
ViewHolder holder = new ViewHolder(view);
return holder; return holder;
} }
@@ -133,30 +141,36 @@ public class ListMessageAdapter extends RecyclerView.Adapter<ListMessageAdapter.
} }
static class ViewHolder extends RecyclerView.ViewHolder { static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.message_image)
ImageView image; ImageView image;
@BindView(R.id.message_text)
TextView message; TextView message;
@BindView(R.id.message_title)
TextView title; TextView title;
@BindView(R.id.message_date)
TextView date; TextView date;
@BindView(R.id.message_delete)
ImageButton delete; ImageButton delete;
private boolean relativeTimeFormat; private boolean relativeTimeFormat;
private OffsetDateTime dateTime; private OffsetDateTime dateTime;
ViewHolder(final View view) { ViewHolder(final ViewBinding binding) {
super(view); super(binding.getRoot());
ButterKnife.bind(this, view);
relativeTimeFormat = true; relativeTimeFormat = true;
dateTime = null; dateTime = null;
enableCopyToClipboard(); enableCopyToClipboard();
if (binding instanceof MessageItemBinding) {
MessageItemBinding localBinding = (MessageItemBinding) binding;
image = localBinding.messageImage;
message = localBinding.messageText;
title = localBinding.messageTitle;
date = localBinding.messageDate;
delete = localBinding.messageDelete;
} else if (binding instanceof MessageItemCompactBinding) {
MessageItemCompactBinding localBinding = (MessageItemCompactBinding) binding;
image = localBinding.messageImage;
message = localBinding.messageText;
title = localBinding.messageTitle;
date = localBinding.messageDate;
delete = localBinding.messageDelete;
}
} }
void switchTimeFormat() { void switchTimeFormat() {

View File

@@ -17,13 +17,12 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.TextView; import android.widget.TextView;
import android.widget.ViewFlipper;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ContextThemeWrapper; import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.view.GravityCompat; import androidx.core.view.GravityCompat;
@@ -34,9 +33,6 @@ import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import com.github.gotify.BuildConfig; import com.github.gotify.BuildConfig;
import com.github.gotify.MissedMessageUtil; import com.github.gotify.MissedMessageUtil;
import com.github.gotify.R; import com.github.gotify.R;
@@ -53,6 +49,7 @@ import com.github.gotify.client.api.MessageApi;
import com.github.gotify.client.model.Application; import com.github.gotify.client.model.Application;
import com.github.gotify.client.model.Client; import com.github.gotify.client.model.Client;
import com.github.gotify.client.model.Message; import com.github.gotify.client.model.Message;
import com.github.gotify.databinding.ActivityMessagesBinding;
import com.github.gotify.init.InitializationActivity; import com.github.gotify.init.InitializationActivity;
import com.github.gotify.log.Log; import com.github.gotify.log.Log;
import com.github.gotify.log.LogsActivity; import com.github.gotify.log.LogsActivity;
@@ -91,24 +88,7 @@ public class MessagesActivity extends AppCompatActivity
private static final int APPLICATION_ORDER = 1; private static final int APPLICATION_ORDER = 1;
@BindView(R.id.toolbar) private ActivityMessagesBinding binding;
Toolbar toolbar;
@BindView(R.id.drawer_layout)
DrawerLayout drawer;
@BindView(R.id.nav_view)
NavigationView navigationView;
@BindView(R.id.messages_view)
RecyclerView messagesView;
@BindView(R.id.swipe_refresh)
SwipeRefreshLayout swipeRefreshLayout;
@BindView(R.id.flipper)
ViewFlipper flipper;
private MessagesModel viewModel; private MessagesModel viewModel;
private boolean isLoadMore = false; private boolean isLoadMore = false;
@@ -119,8 +99,8 @@ public class MessagesActivity extends AppCompatActivity
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messages); binding = ActivityMessagesBinding.inflate(getLayoutInflater());
ButterKnife.bind(this); setContentView(binding.getRoot());
viewModel = viewModel =
new ViewModelProvider(this, new MessagesModelFactory(this)) new ViewModelProvider(this, new MessagesModelFactory(this))
.get(MessagesModel.class); .get(MessagesModel.class);
@@ -129,6 +109,7 @@ public class MessagesActivity extends AppCompatActivity
initDrawer(); initDrawer();
LinearLayoutManager layoutManager = new LinearLayoutManager(this); LinearLayoutManager layoutManager = new LinearLayoutManager(this);
RecyclerView messagesView = binding.messagesView;
DividerItemDecoration dividerItemDecoration = DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration( new DividerItemDecoration(
messagesView.getContext(), layoutManager.getOrientation()); messagesView.getContext(), layoutManager.getOrientation());
@@ -155,8 +136,9 @@ public class MessagesActivity extends AppCompatActivity
new ItemTouchHelper(new SwipeToDeleteCallback(listMessageAdapter)); new ItemTouchHelper(new SwipeToDeleteCallback(listMessageAdapter));
itemTouchHelper.attachToRecyclerView(messagesView); itemTouchHelper.attachToRecyclerView(messagesView);
SwipeRefreshLayout swipeRefreshLayout = binding.swipeRefresh;
swipeRefreshLayout.setOnRefreshListener(this::onRefresh); swipeRefreshLayout.setOnRefreshListener(this::onRefresh);
drawer.addDrawerListener( binding.drawerLayout.addDrawerListener(
new DrawerLayout.SimpleDrawerListener() { new DrawerLayout.SimpleDrawerListener() {
@Override @Override
public void onDrawerClosed(View drawerView) { public void onDrawerClosed(View drawerView) {
@@ -185,6 +167,12 @@ public class MessagesActivity extends AppCompatActivity
new UpdateMessagesForApplication(true).execute(viewModel.getAppId()); new UpdateMessagesForApplication(true).execute(viewModel.getAppId());
} }
@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
binding.learnGotify.setOnClickListener(view -> openDocumentation());
}
public void onRefreshAll(View view) { public void onRefreshAll(View view) {
refreshAll(); refreshAll();
} }
@@ -204,7 +192,6 @@ public class MessagesActivity extends AppCompatActivity
new LoadMore().execute(viewModel.getAppId()); new LoadMore().execute(viewModel.getAppId());
} }
@OnClick(R.id.learn_gotify)
public void openDocumentation() { public void openDocumentation() {
Intent browserIntent = Intent browserIntent =
new Intent(Intent.ACTION_VIEW, Uri.parse("https://gotify.net/docs/pushmsg")); new Intent(Intent.ACTION_VIEW, Uri.parse("https://gotify.net/docs/pushmsg"));
@@ -216,7 +203,7 @@ public class MessagesActivity extends AppCompatActivity
} }
protected void onUpdateApps(List<Application> applications) { protected void onUpdateApps(List<Application> applications) {
Menu menu = navigationView.getMenu(); Menu menu = binding.navView.getMenu();
menu.removeGroup(R.id.apps); menu.removeGroup(R.id.apps);
viewModel.getTargetReferences().clear(); viewModel.getTargetReferences().clear();
updateMessagesAndStopLoading(viewModel.getMessages().get(viewModel.getAppId())); updateMessagesAndStopLoading(viewModel.getMessages().get(viewModel.getAppId()));
@@ -244,20 +231,20 @@ public class MessagesActivity extends AppCompatActivity
} }
private void initDrawer() { private void initDrawer() {
setSupportActionBar(toolbar); setSupportActionBar(binding.appBarDrawer.toolbar);
navigationView.setItemIconTintList(null); binding.navView.setItemIconTintList(null);
ActionBarDrawerToggle toggle = ActionBarDrawerToggle toggle =
new ActionBarDrawerToggle( new ActionBarDrawerToggle(
this, this,
drawer, binding.drawerLayout,
toolbar, binding.appBarDrawer.toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_open,
R.string.navigation_drawer_close); R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle); binding.drawerLayout.addDrawerListener(toggle);
toggle.syncState(); toggle.syncState();
navigationView.setNavigationItemSelectedListener(this); binding.navView.setNavigationItemSelectedListener(this);
View headerView = navigationView.getHeaderView(0); View headerView = binding.navView.getHeaderView(0);
Settings settings = viewModel.getSettings(); Settings settings = viewModel.getSettings();
@@ -278,8 +265,8 @@ public class MessagesActivity extends AppCompatActivity
@Override @Override
public void onBackPressed() { public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) { if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START); binding.drawerLayout.closeDrawer(GravityCompat.START);
} else { } else {
super.onBackPressed(); super.onBackPressed();
} }
@@ -294,11 +281,11 @@ public class MessagesActivity extends AppCompatActivity
Application app = viewModel.getAppsHolder().get().get(id); Application app = viewModel.getAppsHolder().get().get(id);
updateAppOnDrawerClose = app != null ? app.getId() : MessageState.ALL_MESSAGES; updateAppOnDrawerClose = app != null ? app.getId() : MessageState.ALL_MESSAGES;
startLoading(); startLoading();
toolbar.setSubtitle(item.getTitle()); binding.appBarDrawer.toolbar.setSubtitle(item.getTitle());
} else if (id == R.id.nav_all_messages) { } else if (id == R.id.nav_all_messages) {
updateAppOnDrawerClose = MessageState.ALL_MESSAGES; updateAppOnDrawerClose = MessageState.ALL_MESSAGES;
startLoading(); startLoading();
toolbar.setSubtitle(""); binding.appBarDrawer.toolbar.setSubtitle("");
} else if (id == R.id.logout) { } else if (id == R.id.logout) {
new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.AppTheme_Dialog)) new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.AppTheme_Dialog))
.setTitle(R.string.logout) .setTitle(R.string.logout)
@@ -315,7 +302,7 @@ public class MessagesActivity extends AppCompatActivity
startActivity(intent); startActivity(intent);
} }
drawer.closeDrawer(GravityCompat.START); binding.drawerLayout.closeDrawer(GravityCompat.START);
return true; return true;
} }
@@ -325,13 +312,13 @@ public class MessagesActivity extends AppCompatActivity
} }
private void startLoading() { private void startLoading() {
swipeRefreshLayout.setRefreshing(true); binding.swipeRefresh.setRefreshing(true);
messagesView.setVisibility(View.GONE); binding.messagesView.setVisibility(View.GONE);
} }
private void stopLoading() { private void stopLoading() {
swipeRefreshLayout.setRefreshing(false); binding.swipeRefresh.setRefreshing(false);
messagesView.setVisibility(View.VISIBLE); binding.messagesView.setVisibility(View.VISIBLE);
} }
@Override @Override
@@ -359,7 +346,7 @@ public class MessagesActivity extends AppCompatActivity
} }
listMessageAdapter.notifyDataSetChanged(); listMessageAdapter.notifyDataSetChanged();
selectAppInMenu(navigationView.getMenu().findItem(selectedIndex)); selectAppInMenu(binding.navView.getMenu().findItem(selectedIndex));
super.onResume(); super.onResume();
} }
@@ -373,12 +360,12 @@ public class MessagesActivity extends AppCompatActivity
if (appItem != null) { if (appItem != null) {
appItem.setChecked(true); appItem.setChecked(true);
if (appItem.getItemId() != R.id.nav_all_messages) if (appItem.getItemId() != R.id.nav_all_messages)
toolbar.setSubtitle(appItem.getTitle()); binding.appBarDrawer.toolbar.setSubtitle(appItem.getTitle());
} }
} }
private void scheduleDeletion(int position, Message message, boolean listAnimation) { private void scheduleDeletion(int position, Message message, boolean listAnimation) {
ListMessageAdapter adapter = (ListMessageAdapter) messagesView.getAdapter(); ListMessageAdapter adapter = (ListMessageAdapter) binding.messagesView.getAdapter();
MessageFacade messages = viewModel.getMessages(); MessageFacade messages = viewModel.getMessages();
messages.deleteLocal(message); messages.deleteLocal(message);
@@ -394,7 +381,7 @@ public class MessagesActivity extends AppCompatActivity
MessageFacade messages = viewModel.getMessages(); MessageFacade messages = viewModel.getMessages();
MessageDeletion deletion = messages.undoDeleteLocal(); MessageDeletion deletion = messages.undoDeleteLocal();
if (deletion != null) { if (deletion != null) {
ListMessageAdapter adapter = (ListMessageAdapter) messagesView.getAdapter(); ListMessageAdapter adapter = (ListMessageAdapter) binding.messagesView.getAdapter();
long appId = viewModel.getAppId(); long appId = viewModel.getAppId();
adapter.setItems(messages.get(appId)); adapter.setItems(messages.get(appId));
int insertPosition = int insertPosition =
@@ -406,7 +393,7 @@ public class MessagesActivity extends AppCompatActivity
} }
private void showDeletionSnackbar() { private void showDeletionSnackbar() {
View view = swipeRefreshLayout; View view = binding.swipeRefresh;
Snackbar snackbar = Snackbar.make(view, R.string.snackbar_deleted, Snackbar.LENGTH_LONG); Snackbar snackbar = Snackbar.make(view, R.string.snackbar_deleted, Snackbar.LENGTH_LONG);
snackbar.setAction(R.string.snackbar_undo, v -> undoDelete()); snackbar.setAction(R.string.snackbar_undo, v -> undoDelete());
snackbar.addCallback(new SnackbarCallback()); snackbar.addCallback(new SnackbarCallback());
@@ -741,12 +728,12 @@ public class MessagesActivity extends AppCompatActivity
stopLoading(); stopLoading();
if (messageWithImages.isEmpty()) { if (messageWithImages.isEmpty()) {
flipper.setDisplayedChild(1); binding.flipper.setDisplayedChild(1);
} else { } else {
flipper.setDisplayedChild(0); binding.flipper.setDisplayedChild(0);
} }
ListMessageAdapter adapter = (ListMessageAdapter) messagesView.getAdapter(); ListMessageAdapter adapter = (ListMessageAdapter) binding.messagesView.getAdapter();
adapter.setItems(messageWithImages); adapter.setItems(messageWithImages);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }

View File

@@ -6,16 +6,11 @@ import android.os.Bundle;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import com.github.gotify.R; import com.github.gotify.R;
import com.github.gotify.Settings; import com.github.gotify.Settings;
import com.github.gotify.api.Api; import com.github.gotify.api.Api;
@@ -25,6 +20,7 @@ import com.github.gotify.client.ApiClient;
import com.github.gotify.client.api.MessageApi; import com.github.gotify.client.api.MessageApi;
import com.github.gotify.client.model.Application; import com.github.gotify.client.model.Application;
import com.github.gotify.client.model.Message; import com.github.gotify.client.model.Message;
import com.github.gotify.databinding.ActivityShareBinding;
import com.github.gotify.log.Log; import com.github.gotify.log.Log;
import com.github.gotify.messages.provider.ApplicationHolder; import com.github.gotify.messages.provider.ApplicationHolder;
import java.util.ArrayList; import java.util.ArrayList;
@@ -33,35 +29,18 @@ import java.util.List;
import static com.github.gotify.Utils.first; import static com.github.gotify.Utils.first;
public class ShareActivity extends AppCompatActivity { public class ShareActivity extends AppCompatActivity {
private ActivityShareBinding binding;
private Settings settings; private Settings settings;
private ApplicationHolder appsHolder; private ApplicationHolder appsHolder;
@BindView(R.id.title)
EditText edtTxtTitle;
@BindView(R.id.content)
EditText edtTxtContent;
@BindView(R.id.edtTxtPriority)
EditText edtTxtPriority;
@BindView(R.id.appSpinner)
Spinner appSpinner;
@BindView(R.id.push_button)
Button pushMessageButton;
@BindView(R.id.missingAppsContainer)
LinearLayout missingAppsInfo;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share); binding = ActivityShareBinding.inflate(getLayoutInflater());
ButterKnife.bind(this); setContentView(binding.getRoot());
Log.i("Entering " + getClass().getSimpleName()); Log.i("Entering " + getClass().getSimpleName());
setSupportActionBar(findViewById(R.id.toolbar)); setSupportActionBar(binding.appBarDrawer.toolbar);
ActionBar actionBar = getSupportActionBar(); ActionBar actionBar = getSupportActionBar();
if (actionBar != null) { if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true);
@@ -74,7 +53,7 @@ public class ShareActivity extends AppCompatActivity {
if (Intent.ACTION_SEND.equals(intent.getAction()) && "text/plain".equals(type)) { if (Intent.ACTION_SEND.equals(intent.getAction()) && "text/plain".equals(type)) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) { if (sharedText != null) {
edtTxtContent.setText(sharedText); binding.content.setText(sharedText);
} }
} }
@@ -94,13 +73,20 @@ public class ShareActivity extends AppCompatActivity {
populateSpinner(apps); populateSpinner(apps);
boolean appsAvailable = !apps.isEmpty(); boolean appsAvailable = !apps.isEmpty();
pushMessageButton.setEnabled(appsAvailable); binding.pushButton.setEnabled(appsAvailable);
missingAppsInfo.setVisibility(appsAvailable ? View.GONE : View.VISIBLE); binding.missingAppsContainer.setVisibility(
appsAvailable ? View.GONE : View.VISIBLE);
}); });
appsHolder.onUpdateFailed(() -> pushMessageButton.setEnabled(false)); appsHolder.onUpdateFailed(() -> binding.pushButton.setEnabled(false));
appsHolder.request(); appsHolder.request();
} }
@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
binding.pushButton.setOnClickListener(ignored -> pushMessage());
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) { if (item.getItemId() == android.R.id.home) {
@@ -109,12 +95,11 @@ public class ShareActivity extends AppCompatActivity {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@OnClick(R.id.push_button) public void pushMessage() {
public void pushMessage(View view) { String titleText = binding.title.getText().toString();
String titleText = edtTxtTitle.getText().toString(); String contentText = binding.content.getText().toString();
String contentText = edtTxtContent.getText().toString(); String priority = binding.edtTxtPriority.getText().toString();
String priority = edtTxtPriority.getText().toString(); int appIndex = binding.appSpinner.getSelectedItemPosition();
int appIndex = appSpinner.getSelectedItemPosition();
if (contentText.isEmpty()) { if (contentText.isEmpty()) {
Toast.makeText(this, "Content should not be empty.", Toast.LENGTH_LONG).show(); Toast.makeText(this, "Content should not be empty.", Toast.LENGTH_LONG).show();
@@ -147,7 +132,7 @@ public class ShareActivity extends AppCompatActivity {
ArrayAdapter<String> adapter = ArrayAdapter<String> adapter =
new ArrayAdapter<>( new ArrayAdapter<>(
this, android.R.layout.simple_spinner_dropdown_item, appNameList); this, android.R.layout.simple_spinner_dropdown_item, appNameList);
appSpinner.setAdapter(adapter); binding.appSpinner.setAdapter(adapter);
} }
private class PushMessage extends AsyncTask<Message, String, String> { private class PushMessage extends AsyncTask<Message, String, String> {

View File

@@ -36,6 +36,7 @@
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
<include <include
android:id="@+id/app_bar_drawer"
layout="@layout/app_bar_drawer" layout="@layout/app_bar_drawer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />

View File

@@ -80,6 +80,7 @@
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<include <include
android:id="@+id/app_bar_drawer"
layout="@layout/app_bar_drawer" layout="@layout/app_bar_drawer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />

View File

@@ -11,6 +11,7 @@
android:orientation="vertical"> android:orientation="vertical">
<include <include
android:id="@+id/app_bar_drawer"
layout="@layout/app_bar_drawer" layout="@layout/app_bar_drawer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />