diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java index 19b52c9e..0a6d9fae 100644 --- a/app/src/main/java/eu/faircode/email/ActivityView.java +++ b/app/src/main/java/eu/faircode/email/ActivityView.java @@ -27,6 +27,7 @@ import android.content.res.Configuration; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.preference.PreferenceManager; import android.util.Log; import android.view.LayoutInflater; import android.view.MenuItem; @@ -110,6 +111,9 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack case R.string.menu_setup: onMenuSetup(); break; + case R.string.menu_operations: + onMenuOperations(); + break; case R.string.menu_faq: onMenuFAQ(); break; @@ -145,8 +149,13 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack } drawerArray.add(new DrawerItem(ActivityView.this, R.drawable.baseline_settings_applications_24, R.string.menu_setup)); + + if (PreferenceManager.getDefaultSharedPreferences(ActivityView.this).getBoolean("debug", false)) + drawerArray.add(new DrawerItem(ActivityView.this, R.drawable.baseline_list_24, R.string.menu_operations)); + if (getIntentFAQ().resolveActivity(getPackageManager()) != null) drawerArray.add(new DrawerItem(ActivityView.this, R.drawable.baseline_question_answer_24, R.string.menu_faq)); + drawerArray.add(new DrawerItem(ActivityView.this, R.drawable.baseline_help_24, R.string.menu_about)); drawerList.setAdapter(drawerArray); @@ -394,6 +403,12 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack startActivity(new Intent(ActivityView.this, ActivitySetup.class)); } + private void onMenuOperations() { + FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); + fragmentTransaction.replace(R.id.content_frame, new FragmentOperations()).addToBackStack("operations"); + fragmentTransaction.commit(); + } + private void onMenuFAQ() { startActivity(getIntentFAQ()); } diff --git a/app/src/main/java/eu/faircode/email/AdapterOperation.java b/app/src/main/java/eu/faircode/email/AdapterOperation.java new file mode 100644 index 00000000..00f0e686 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/AdapterOperation.java @@ -0,0 +1,192 @@ +package eu.faircode.email; + +/* + This file is part of Safe email. + + Safe email is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NetGuard is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NetGuard. If not, see . + + Copyright 2018 by Marcel Bokhorst (M66B) +*/ + +import android.content.Context; +import android.content.Intent; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import androidx.annotation.NonNull; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; +import androidx.recyclerview.widget.DiffUtil; +import androidx.recyclerview.widget.ListUpdateCallback; +import androidx.recyclerview.widget.RecyclerView; + +public class AdapterOperation extends RecyclerView.Adapter { + private Context context; + + private List all = new ArrayList<>(); + private List filtered = new ArrayList<>(); + + private DateFormat df = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.LONG); + + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + View itemView; + TextView tvMessage; + TextView tvName; + TextView tvTime; + + ViewHolder(View itemView) { + super(itemView); + + this.itemView = itemView; + tvMessage = itemView.findViewById(R.id.tvMessage); + tvName = itemView.findViewById(R.id.tvName); + tvTime = itemView.findViewById(R.id.tvTime); + } + + private void wire() { + itemView.setOnClickListener(this); + } + + private void unwire() { + itemView.setOnClickListener(null); + } + + private void bindTo(EntityOperation operation) { + tvMessage.setText(Long.toString(operation.message)); + tvName.setText(operation.name); + tvTime.setText(df.format(new Date(operation.created))); + } + + @Override + public void onClick(View view) { + int pos = getAdapterPosition(); + if (pos == RecyclerView.NO_POSITION) + return; + EntityOperation operation = filtered.get(pos); + + LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); + lbm.sendBroadcast( + new Intent(ActivityView.ACTION_VIEW_MESSAGE) + .putExtra("id", operation.message)); + } + } + + AdapterOperation(Context context) { + this.context = context; + setHasStableIds(true); + } + + public void set(@NonNull List operations) { + Log.i(Helper.TAG, "Set operations=" + operations.size()); + + all.clear(); + all.addAll(operations); + + DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new MessageDiffCallback(filtered, all)); + + filtered.clear(); + filtered.addAll(all); + + diff.dispatchUpdatesTo(new ListUpdateCallback() { + @Override + public void onInserted(int position, int count) { + Log.i(Helper.TAG, "Inserted @" + position + " #" + count); + } + + @Override + public void onRemoved(int position, int count) { + Log.i(Helper.TAG, "Removed @" + position + " #" + count); + } + + @Override + public void onMoved(int fromPosition, int toPosition) { + Log.i(Helper.TAG, "Moved " + fromPosition + ">" + toPosition); + } + + @Override + public void onChanged(int position, int count, Object payload) { + Log.i(Helper.TAG, "Changed @" + position + " #" + count); + } + }); + diff.dispatchUpdatesTo(AdapterOperation.this); + } + + private class MessageDiffCallback extends DiffUtil.Callback { + private List prev; + private List next; + + MessageDiffCallback(List prev, List next) { + this.prev = prev; + this.next = next; + } + + @Override + public int getOldListSize() { + return prev.size(); + } + + @Override + public int getNewListSize() { + return next.size(); + } + + @Override + public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { + EntityOperation a1 = prev.get(oldItemPosition); + EntityOperation a2 = next.get(newItemPosition); + return a1.id.equals(a2.id); + } + + @Override + public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { + EntityOperation a1 = prev.get(oldItemPosition); + EntityOperation a2 = next.get(newItemPosition); + return a1.equals(a2); + } + } + + @Override + public long getItemId(int position) { + return filtered.get(position).id; + } + + @Override + public int getItemCount() { + return filtered.size(); + } + + @Override + @NonNull + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_operation, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + holder.unwire(); + + EntityOperation operation = filtered.get(position); + holder.bindTo(operation); + + holder.wire(); + } +} diff --git a/app/src/main/java/eu/faircode/email/DaoOperation.java b/app/src/main/java/eu/faircode/email/DaoOperation.java index c8734081..bd4a60cd 100644 --- a/app/src/main/java/eu/faircode/email/DaoOperation.java +++ b/app/src/main/java/eu/faircode/email/DaoOperation.java @@ -34,6 +34,9 @@ public interface DaoOperation { @Query("SELECT * FROM operation WHERE folder = :folder ORDER BY id") List getOperationsByFolder(long folder); + @Query("SELECT * FROM operation ORDER BY id") + LiveData> liveOperations(); + @Query("SELECT COUNT(id) FROM operation WHERE folder = :folder") int getOperationCount(long folder); diff --git a/app/src/main/java/eu/faircode/email/FragmentOperations.java b/app/src/main/java/eu/faircode/email/FragmentOperations.java new file mode 100644 index 00000000..edab0859 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/FragmentOperations.java @@ -0,0 +1,86 @@ +package eu.faircode.email; + +/* + This file is part of Safe email. + + Safe email is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NetGuard is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NetGuard. If not, see . + + Copyright 2018 by Marcel Bokhorst (M66B) +*/ + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; + +import java.util.List; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.Group; +import androidx.lifecycle.Observer; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +public class FragmentOperations extends FragmentEx { + private RecyclerView rvOperation; + private ProgressBar pbWait; + private Group grpReady; + + private AdapterOperation adapter; + + @Override + @Nullable + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_operations, container, false); + + // Get controls + rvOperation = view.findViewById(R.id.rvOperation); + pbWait = view.findViewById(R.id.pbWait); + grpReady = view.findViewById(R.id.grpReady); + + // Wire controls + + rvOperation.setHasFixedSize(false); + LinearLayoutManager llm = new LinearLayoutManager(getContext()); + rvOperation.setLayoutManager(llm); + + adapter = new AdapterOperation(getContext()); + rvOperation.setAdapter(adapter); + + // Initialize + grpReady.setVisibility(View.GONE); + pbWait.setVisibility(View.VISIBLE); + + return view; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + // Observe folders + DB.getInstance(getContext()).operation().liveOperations().observe(getViewLifecycleOwner(), new Observer>() { + @Override + public void onChanged(@Nullable List operations) { + if (operations != null) + adapter.set(operations); + + pbWait.setVisibility(View.GONE); + grpReady.setVisibility(View.VISIBLE); + } + }); + } +} diff --git a/app/src/main/res/drawable-hdpi/baseline_list_black_18.png b/app/src/main/res/drawable-hdpi/baseline_list_black_18.png new file mode 100755 index 00000000..26e40d8d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/baseline_list_black_18.png differ diff --git a/app/src/main/res/drawable-hdpi/baseline_list_black_24.png b/app/src/main/res/drawable-hdpi/baseline_list_black_24.png new file mode 100755 index 00000000..094529c6 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/baseline_list_black_24.png differ diff --git a/app/src/main/res/drawable-hdpi/baseline_list_black_36.png b/app/src/main/res/drawable-hdpi/baseline_list_black_36.png new file mode 100755 index 00000000..eb748fdb Binary files /dev/null and b/app/src/main/res/drawable-hdpi/baseline_list_black_36.png differ diff --git a/app/src/main/res/drawable-hdpi/baseline_list_black_48.png b/app/src/main/res/drawable-hdpi/baseline_list_black_48.png new file mode 100755 index 00000000..d94b45a1 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/baseline_list_black_48.png differ diff --git a/app/src/main/res/drawable-hdpi/baseline_list_white_18.png b/app/src/main/res/drawable-hdpi/baseline_list_white_18.png new file mode 100755 index 00000000..ceea6301 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/baseline_list_white_18.png differ diff --git a/app/src/main/res/drawable-hdpi/baseline_list_white_24.png b/app/src/main/res/drawable-hdpi/baseline_list_white_24.png new file mode 100755 index 00000000..c8653197 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/baseline_list_white_24.png differ diff --git a/app/src/main/res/drawable-hdpi/baseline_list_white_36.png b/app/src/main/res/drawable-hdpi/baseline_list_white_36.png new file mode 100755 index 00000000..8b229dfa Binary files /dev/null and b/app/src/main/res/drawable-hdpi/baseline_list_white_36.png differ diff --git a/app/src/main/res/drawable-hdpi/baseline_list_white_48.png b/app/src/main/res/drawable-hdpi/baseline_list_white_48.png new file mode 100755 index 00000000..4d2807e4 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/baseline_list_white_48.png differ diff --git a/app/src/main/res/drawable-mdpi/baseline_list_black_18.png b/app/src/main/res/drawable-mdpi/baseline_list_black_18.png new file mode 100755 index 00000000..a16143bb Binary files /dev/null and b/app/src/main/res/drawable-mdpi/baseline_list_black_18.png differ diff --git a/app/src/main/res/drawable-mdpi/baseline_list_black_24.png b/app/src/main/res/drawable-mdpi/baseline_list_black_24.png new file mode 100755 index 00000000..3d810945 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/baseline_list_black_24.png differ diff --git a/app/src/main/res/drawable-mdpi/baseline_list_black_36.png b/app/src/main/res/drawable-mdpi/baseline_list_black_36.png new file mode 100755 index 00000000..094529c6 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/baseline_list_black_36.png differ diff --git a/app/src/main/res/drawable-mdpi/baseline_list_black_48.png b/app/src/main/res/drawable-mdpi/baseline_list_black_48.png new file mode 100755 index 00000000..3351e6fb Binary files /dev/null and b/app/src/main/res/drawable-mdpi/baseline_list_black_48.png differ diff --git a/app/src/main/res/drawable-mdpi/baseline_list_white_18.png b/app/src/main/res/drawable-mdpi/baseline_list_white_18.png new file mode 100755 index 00000000..e44b03fa Binary files /dev/null and b/app/src/main/res/drawable-mdpi/baseline_list_white_18.png differ diff --git a/app/src/main/res/drawable-mdpi/baseline_list_white_24.png b/app/src/main/res/drawable-mdpi/baseline_list_white_24.png new file mode 100755 index 00000000..61f9280d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/baseline_list_white_24.png differ diff --git a/app/src/main/res/drawable-mdpi/baseline_list_white_36.png b/app/src/main/res/drawable-mdpi/baseline_list_white_36.png new file mode 100755 index 00000000..c8653197 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/baseline_list_white_36.png differ diff --git a/app/src/main/res/drawable-mdpi/baseline_list_white_48.png b/app/src/main/res/drawable-mdpi/baseline_list_white_48.png new file mode 100755 index 00000000..2b725397 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/baseline_list_white_48.png differ diff --git a/app/src/main/res/drawable-xhdpi/baseline_list_black_18.png b/app/src/main/res/drawable-xhdpi/baseline_list_black_18.png new file mode 100755 index 00000000..094529c6 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/baseline_list_black_18.png differ diff --git a/app/src/main/res/drawable-xhdpi/baseline_list_black_24.png b/app/src/main/res/drawable-xhdpi/baseline_list_black_24.png new file mode 100755 index 00000000..3351e6fb Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/baseline_list_black_24.png differ diff --git a/app/src/main/res/drawable-xhdpi/baseline_list_black_36.png b/app/src/main/res/drawable-xhdpi/baseline_list_black_36.png new file mode 100755 index 00000000..d94b45a1 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/baseline_list_black_36.png differ diff --git a/app/src/main/res/drawable-xhdpi/baseline_list_black_48.png b/app/src/main/res/drawable-xhdpi/baseline_list_black_48.png new file mode 100755 index 00000000..e1f03b45 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/baseline_list_black_48.png differ diff --git a/app/src/main/res/drawable-xhdpi/baseline_list_white_18.png b/app/src/main/res/drawable-xhdpi/baseline_list_white_18.png new file mode 100755 index 00000000..c8653197 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/baseline_list_white_18.png differ diff --git a/app/src/main/res/drawable-xhdpi/baseline_list_white_24.png b/app/src/main/res/drawable-xhdpi/baseline_list_white_24.png new file mode 100755 index 00000000..2b725397 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/baseline_list_white_24.png differ diff --git a/app/src/main/res/drawable-xhdpi/baseline_list_white_36.png b/app/src/main/res/drawable-xhdpi/baseline_list_white_36.png new file mode 100755 index 00000000..4d2807e4 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/baseline_list_white_36.png differ diff --git a/app/src/main/res/drawable-xhdpi/baseline_list_white_48.png b/app/src/main/res/drawable-xhdpi/baseline_list_white_48.png new file mode 100755 index 00000000..2a6d3b04 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/baseline_list_white_48.png differ diff --git a/app/src/main/res/drawable-xxhdpi/baseline_list_black_18.png b/app/src/main/res/drawable-xxhdpi/baseline_list_black_18.png new file mode 100755 index 00000000..eb748fdb Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/baseline_list_black_18.png differ diff --git a/app/src/main/res/drawable-xxhdpi/baseline_list_black_24.png b/app/src/main/res/drawable-xxhdpi/baseline_list_black_24.png new file mode 100755 index 00000000..d94b45a1 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/baseline_list_black_24.png differ diff --git a/app/src/main/res/drawable-xxhdpi/baseline_list_black_36.png b/app/src/main/res/drawable-xxhdpi/baseline_list_black_36.png new file mode 100755 index 00000000..b17298e5 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/baseline_list_black_36.png differ diff --git a/app/src/main/res/drawable-xxhdpi/baseline_list_black_48.png b/app/src/main/res/drawable-xxhdpi/baseline_list_black_48.png new file mode 100755 index 00000000..7ddaf525 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/baseline_list_black_48.png differ diff --git a/app/src/main/res/drawable-xxhdpi/baseline_list_white_18.png b/app/src/main/res/drawable-xxhdpi/baseline_list_white_18.png new file mode 100755 index 00000000..8b229dfa Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/baseline_list_white_18.png differ diff --git a/app/src/main/res/drawable-xxhdpi/baseline_list_white_24.png b/app/src/main/res/drawable-xxhdpi/baseline_list_white_24.png new file mode 100755 index 00000000..4d2807e4 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/baseline_list_white_24.png differ diff --git a/app/src/main/res/drawable-xxhdpi/baseline_list_white_36.png b/app/src/main/res/drawable-xxhdpi/baseline_list_white_36.png new file mode 100755 index 00000000..5efe1938 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/baseline_list_white_36.png differ diff --git a/app/src/main/res/drawable-xxhdpi/baseline_list_white_48.png b/app/src/main/res/drawable-xxhdpi/baseline_list_white_48.png new file mode 100755 index 00000000..eb80f8b1 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/baseline_list_white_48.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/baseline_list_black_18.png b/app/src/main/res/drawable-xxxhdpi/baseline_list_black_18.png new file mode 100755 index 00000000..d94b45a1 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/baseline_list_black_18.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/baseline_list_black_24.png b/app/src/main/res/drawable-xxxhdpi/baseline_list_black_24.png new file mode 100755 index 00000000..e1f03b45 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/baseline_list_black_24.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/baseline_list_black_36.png b/app/src/main/res/drawable-xxxhdpi/baseline_list_black_36.png new file mode 100755 index 00000000..7ddaf525 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/baseline_list_black_36.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/baseline_list_black_48.png b/app/src/main/res/drawable-xxxhdpi/baseline_list_black_48.png new file mode 100755 index 00000000..fc032a97 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/baseline_list_black_48.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/baseline_list_white_18.png b/app/src/main/res/drawable-xxxhdpi/baseline_list_white_18.png new file mode 100755 index 00000000..4d2807e4 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/baseline_list_white_18.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/baseline_list_white_24.png b/app/src/main/res/drawable-xxxhdpi/baseline_list_white_24.png new file mode 100755 index 00000000..2a6d3b04 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/baseline_list_white_24.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/baseline_list_white_36.png b/app/src/main/res/drawable-xxxhdpi/baseline_list_white_36.png new file mode 100755 index 00000000..eb80f8b1 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/baseline_list_white_36.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/baseline_list_white_48.png b/app/src/main/res/drawable-xxxhdpi/baseline_list_white_48.png new file mode 100755 index 00000000..c093cb17 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/baseline_list_white_48.png differ diff --git a/app/src/main/res/drawable/baseline_list_24.xml b/app/src/main/res/drawable/baseline_list_24.xml new file mode 100755 index 00000000..555080ba --- /dev/null +++ b/app/src/main/res/drawable/baseline_list_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/fragment_operations.xml b/app/src/main/res/layout/fragment_operations.xml new file mode 100644 index 00000000..86d4d5fa --- /dev/null +++ b/app/src/main/res/layout/fragment_operations.xml @@ -0,0 +1,36 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/item_operation.xml b/app/src/main/res/layout/item_operation.xml new file mode 100644 index 00000000..6ab7587c --- /dev/null +++ b/app/src/main/res/layout/item_operation.xml @@ -0,0 +1,38 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fd711908..9191a3ec 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,6 +32,7 @@ \'%1$s\' failed Setup + Operations FAQ About