diff --git a/app/src/main/java/org/isoron/uhabits/commands/DeleteHabitsCommand.java b/app/src/main/java/org/isoron/uhabits/commands/DeleteHabitsCommand.java index 6dff1f59d..7e4e201eb 100644 --- a/app/src/main/java/org/isoron/uhabits/commands/DeleteHabitsCommand.java +++ b/app/src/main/java/org/isoron/uhabits/commands/DeleteHabitsCommand.java @@ -41,7 +41,7 @@ public class DeleteHabitsCommand extends Command @Override public void undo() { - + throw new UnsupportedOperationException(); } public Integer getExecuteStringId() diff --git a/app/src/main/java/org/isoron/uhabits/commands/EditHabitCommand.java b/app/src/main/java/org/isoron/uhabits/commands/EditHabitCommand.java index 53b4bbf1b..985275f40 100644 --- a/app/src/main/java/org/isoron/uhabits/commands/EditHabitCommand.java +++ b/app/src/main/java/org/isoron/uhabits/commands/EditHabitCommand.java @@ -33,8 +33,8 @@ public class EditHabitCommand extends Command this.modified = new Habit(modified); this.original = new Habit(original); - hasIntervalChanged = (this.original.freqDen != this.modified.freqDen || - this.original.freqNum != this.modified.freqNum); + hasIntervalChanged = (!this.original.freqDen.equals(this.modified.freqDen) || + !this.original.freqNum.equals(this.modified.freqNum)); } public void execute() diff --git a/app/src/main/java/org/isoron/uhabits/dialogs/HabitSelectionCallback.java b/app/src/main/java/org/isoron/uhabits/dialogs/HabitSelectionCallback.java new file mode 100644 index 000000000..2283ffb9d --- /dev/null +++ b/app/src/main/java/org/isoron/uhabits/dialogs/HabitSelectionCallback.java @@ -0,0 +1,268 @@ +/* Copyright (C) 2016 Alinson Santos Xavier + * + * This program 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. + * + * This program 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 this program. If not, see . + */ + +package org.isoron.uhabits.dialogs; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.os.AsyncTask; +import android.view.ActionMode; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.ProgressBar; + +import com.android.colorpicker.ColorPickerDialog; +import com.android.colorpicker.ColorPickerSwatch; + +import org.isoron.helpers.ColorHelper; +import org.isoron.helpers.DialogHelper; +import org.isoron.helpers.ReplayableActivity; +import org.isoron.uhabits.R; +import org.isoron.uhabits.commands.ArchiveHabitsCommand; +import org.isoron.uhabits.commands.ChangeHabitColorCommand; +import org.isoron.uhabits.commands.DeleteHabitsCommand; +import org.isoron.uhabits.commands.UnarchiveHabitsCommand; +import org.isoron.uhabits.fragments.EditHabitFragment; +import org.isoron.uhabits.io.CSVExporter; +import org.isoron.uhabits.loaders.HabitListLoader; +import org.isoron.uhabits.models.Habit; + +import java.io.File; +import java.util.LinkedList; +import java.util.List; + +public class HabitSelectionCallback implements ActionMode.Callback +{ + private HabitListLoader loader; + private List selectedPositions; + private ReplayableActivity activity; + private Listener listener; + private DialogHelper.OnSavedListener onSavedListener; + private ProgressBar progressBar; + + public interface Listener + { + void onActionModeDestroyed(ActionMode mode); + } + + public HabitSelectionCallback(ReplayableActivity activity, HabitListLoader loader) + { + this.activity = activity; + this.loader = loader; + selectedPositions = new LinkedList<>(); + } + + public void setListener(Listener listener) + { + this.listener = listener; + } + + public void setProgressBar(ProgressBar progressBar) + { + this.progressBar = progressBar; + } + + public void setOnSavedListener(DialogHelper.OnSavedListener onSavedListener) + { + this.onSavedListener = onSavedListener; + } + + public void setSelectedPositions(List selectedPositions) + { + this.selectedPositions = selectedPositions; + } + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) + { + activity.getMenuInflater().inflate(R.menu.list_habits_context, menu); + updateTitle(mode); + updateActions(menu); + return true; + } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) + { + updateTitle(mode); + updateActions(menu); + return true; + } + + private void updateActions(Menu menu) + { + boolean showEdit = (selectedPositions.size() == 1); + boolean showColor = true; + boolean showArchive = true; + boolean showUnarchive = true; + + if (showEdit) showColor = false; + for (int i : selectedPositions) + { + Habit h = loader.habitsList.get(i); + if (h.isArchived()) + { + showColor = false; + showArchive = false; + } + else showUnarchive = false; + } + + MenuItem itemEdit = menu.findItem(R.id.action_edit_habit); + MenuItem itemColor = menu.findItem(R.id.action_color); + MenuItem itemArchive = menu.findItem(R.id.action_archive_habit); + MenuItem itemUnarchive = menu.findItem(R.id.action_unarchive_habit); + + itemEdit.setVisible(showEdit); + itemColor.setVisible(showColor); + itemArchive.setVisible(showArchive); + itemUnarchive.setVisible(showUnarchive); + } + + private void updateTitle(ActionMode mode) + { + mode.setTitle("" + selectedPositions.size()); + } + + @Override + public boolean onActionItemClicked(final ActionMode mode, MenuItem item) + { + final LinkedList selectedHabits = new LinkedList<>(); + for (int i : selectedPositions) + selectedHabits.add(loader.habitsList.get(i)); + + Habit firstHabit = selectedHabits.getFirst(); + + switch (item.getItemId()) + { + case R.id.action_archive_habit: + activity.executeCommand(new ArchiveHabitsCommand(selectedHabits), null); + mode.finish(); + return true; + + case R.id.action_unarchive_habit: + activity.executeCommand(new UnarchiveHabitsCommand(selectedHabits), null); + mode.finish(); + return true; + + case R.id.action_edit_habit: + { + EditHabitFragment frag = EditHabitFragment.editSingleHabitFragment(firstHabit.getId()); + frag.setOnSavedListener(onSavedListener); + frag.show(activity.getFragmentManager(), "dialog"); + return true; + } + + case R.id.action_color: + { + ColorPickerDialog picker = ColorPickerDialog.newInstance(R.string.color_picker_default_title, + ColorHelper.palette, firstHabit.color, 4, ColorPickerDialog.SIZE_SMALL); + + picker.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener() + { + public void onColorSelected(int color) + { + activity.executeCommand( + new ChangeHabitColorCommand(selectedHabits, color), null); + mode.finish(); + } + }); + picker.show(activity.getFragmentManager(), "picker"); + return true; + } + + case R.id.action_delete: + { + new AlertDialog.Builder(activity).setTitle(R.string.delete_habits) + .setMessage(R.string.delete_habits_message) + .setPositiveButton(android.R.string.yes, + new DialogInterface.OnClickListener() + { + @Override + public void onClick(DialogInterface dialog, int which) + { + activity.executeCommand( + new DeleteHabitsCommand(selectedHabits), null); + mode.finish(); + } + }).setNegativeButton(android.R.string.no, null) + .show(); + + return true; + } + + case R.id.action_export_csv: + { + onExportHabitsClick(selectedHabits); + return true; + } + } + + return false; + } + + @Override + public void onDestroyActionMode(ActionMode mode) + { + if(listener != null) listener.onActionModeDestroyed(mode); + } + + private void onExportHabitsClick(final LinkedList selectedHabits) + { + new AsyncTask() + { + String filename; + + @Override + protected void onPreExecute() + { + if(progressBar != null) + { + progressBar.setIndeterminate(true); + progressBar.setVisibility(View.VISIBLE); + } + } + + @Override + protected void onPostExecute(Void aVoid) + { + if(filename != null) + { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_SEND); + intent.setType("application/zip"); + intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(filename))); + + activity.startActivity(intent); + } + + if(progressBar != null) + progressBar.setVisibility(View.GONE); + } + + @Override + protected Void doInBackground(Void... params) + { + CSVExporter exporter = new CSVExporter(activity, selectedHabits); + filename = exporter.writeArchive(); + return null; + } + }.execute(); + } +} diff --git a/app/src/main/java/org/isoron/uhabits/dialogs/HintManager.java b/app/src/main/java/org/isoron/uhabits/dialogs/HintManager.java new file mode 100644 index 000000000..eee95a27d --- /dev/null +++ b/app/src/main/java/org/isoron/uhabits/dialogs/HintManager.java @@ -0,0 +1,78 @@ +/* Copyright (C) 2016 Alinson Santos Xavier + * + * This program 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. + * + * This program 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 this program. If not, see . + */ + +package org.isoron.uhabits.dialogs; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.view.View; +import android.widget.TextView; + +import org.isoron.helpers.DateHelper; +import org.isoron.uhabits.R; + +public class HintManager +{ + private Context context; + private SharedPreferences prefs; + private View hintView; + + public HintManager(Context context, View hintView) + { + this.context = context; + this.hintView = hintView; + prefs = PreferenceManager.getDefaultSharedPreferences(context); + } + + public void dismissHint() + { + hintView.animate().alpha(0f).setDuration(500).setListener(new AnimatorListenerAdapter() + { + @Override + public void onAnimationEnd(Animator animation) + { + hintView.setVisibility(View.GONE); + } + }); + } + + public void showHintIfAppropriate() + { + Integer lastHintNumber = prefs.getInt("last_hint_number", -1); + Long lastHintTimestamp = prefs.getLong("last_hint_timestamp", -1); + + if (DateHelper.getStartOfToday() > lastHintTimestamp) showHint(lastHintNumber + 1); + } + + private void showHint(int hintNumber) + { + String[] hints = context.getResources().getStringArray(R.array.hints); + if (hintNumber >= hints.length) return; + + prefs.edit().putInt("last_hint_number", hintNumber).apply(); + prefs.edit().putLong("last_hint_timestamp", DateHelper.getStartOfToday()).apply(); + + TextView tvContent = (TextView) hintView.findViewById(R.id.hintContent); + tvContent.setText(hints[hintNumber]); + + hintView.setAlpha(0.0f); + hintView.setVisibility(View.VISIBLE); + hintView.animate().alpha(1f).setDuration(500); + } +} diff --git a/app/src/main/java/org/isoron/uhabits/fragments/EditHabitFragment.java b/app/src/main/java/org/isoron/uhabits/fragments/EditHabitFragment.java index 82a32d37d..cef7fa916 100644 --- a/app/src/main/java/org/isoron/uhabits/fragments/EditHabitFragment.java +++ b/app/src/main/java/org/isoron/uhabits/fragments/EditHabitFragment.java @@ -57,13 +57,20 @@ public class EditHabitFragment extends DialogFragment private OnSavedListener onSavedListener; - private Habit originalHabit, modifiedHabit; - private TextView tvName, tvDescription, tvFreqNum, tvFreqDen, tvReminderTime, tvReminderDays; + private Habit originalHabit; + private Habit modifiedHabit; + + private TextView tvName; + private TextView tvDescription; + private TextView tvFreqNum; + private TextView tvFreqDen; + private TextView tvReminderTime; + private TextView tvReminderDays; private SharedPreferences prefs; private boolean is24HourMode; - static EditHabitFragment editSingleHabitFragment(long id) + public static EditHabitFragment editSingleHabitFragment(long id) { EditHabitFragment frag = new EditHabitFragment(); Bundle args = new Bundle(); @@ -73,7 +80,7 @@ public class EditHabitFragment extends DialogFragment return frag; } - static EditHabitFragment createHabitFragment() + public static EditHabitFragment createHabitFragment() { EditHabitFragment frag = new EditHabitFragment(); Bundle args = new Bundle(); @@ -96,13 +103,13 @@ public class EditHabitFragment extends DialogFragment Button buttonSave = (Button) view.findViewById(R.id.buttonSave); Button buttonDiscard = (Button) view.findViewById(R.id.buttonDiscard); + ImageButton buttonPickColor = (ImageButton) view.findViewById(R.id.buttonPickColor); buttonSave.setOnClickListener(this); buttonDiscard.setOnClickListener(this); tvReminderTime.setOnClickListener(this); tvReminderDays.setOnClickListener(this); - - ImageButton buttonPickColor = (ImageButton) view.findViewById(R.id.buttonPickColor); + buttonPickColor.setOnClickListener(this); prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); @@ -140,8 +147,6 @@ public class EditHabitFragment extends DialogFragment changeColor(modifiedHabit.color); updateReminder(); - buttonPickColor.setOnClickListener(this); - return view; } @@ -225,8 +230,6 @@ public class EditHabitFragment extends DialogFragment private void onSaveButtonClick() { - Command command = null; - modifiedHabit.name = tvName.getText().toString().trim(); modifiedHabit.description = tvDescription.getText().toString().trim(); modifiedHabit.freqNum = Integer.parseInt(tvFreqNum.getText().toString()); @@ -239,6 +242,7 @@ public class EditHabitFragment extends DialogFragment editor.putInt("pref_default_habit_freq_den", modifiedHabit.freqDen); editor.apply(); + Command command = null; Habit savedHabit = null; if (mode == EDIT_MODE) @@ -246,8 +250,10 @@ public class EditHabitFragment extends DialogFragment command = new EditHabitCommand(originalHabit, modifiedHabit); savedHabit = originalHabit; } - - if (mode == CREATE_MODE) command = new CreateHabitCommand(modifiedHabit); + else if (mode == CREATE_MODE) + { + command = new CreateHabitCommand(modifiedHabit); + } if (onSavedListener != null) onSavedListener.onSaved(command, savedHabit); @@ -325,6 +331,7 @@ public class EditHabitFragment extends DialogFragment int count = 0; for(int i = 0; i < 7; i++) if(selectedDays[i]) count++; + if(count == 0) Arrays.fill(selectedDays, true); modifiedHabit.reminderDays = DateHelper.packWeekdayList(selectedDays); diff --git a/app/src/main/java/org/isoron/uhabits/fragments/HabitListAdapter.java b/app/src/main/java/org/isoron/uhabits/fragments/HabitListAdapter.java new file mode 100644 index 000000000..32379e678 --- /dev/null +++ b/app/src/main/java/org/isoron/uhabits/fragments/HabitListAdapter.java @@ -0,0 +1,97 @@ +package org.isoron.uhabits.fragments; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.isoron.helpers.DateHelper; +import org.isoron.uhabits.R; +import org.isoron.uhabits.helpers.ListHabitsHelper; +import org.isoron.uhabits.loaders.HabitListLoader; +import org.isoron.uhabits.models.Habit; + +import java.util.List; + +class HabitListAdapter extends BaseAdapter +{ + private LayoutInflater inflater; + private HabitListLoader loader; + private ListHabitsHelper helper; + private List selectedPositions; + private View.OnLongClickListener onCheckmarkLongClickListener; + private View.OnClickListener onCheckmarkClickListener; + + public HabitListAdapter(Context context, HabitListLoader loader) + { + this.loader = loader; + + inflater = LayoutInflater.from(context); + helper = new ListHabitsHelper(context, loader); + } + + @Override + public int getCount() + { + return loader.habits.size(); + } + + @Override + public Object getItem(int position) + { + return loader.habitsList.get(position); + } + + @Override + public long getItemId(int position) + { + return ((Habit) getItem(position)).getId(); + } + + @Override + public View getView(int position, View view, ViewGroup parent) + { + final Habit habit = loader.habitsList.get(position); + + if (view == null || (Long) view.getTag(R.id.timestamp_key) != DateHelper.getStartOfToday()) + { + view = inflater.inflate(R.layout.list_habits_item, null); + helper.initializeLabelAndIcon(view); + helper.inflateCheckmarkButtons(view, onCheckmarkLongClickListener, + onCheckmarkClickListener, inflater); + } + + TextView tvStar = ((TextView) view.findViewById(R.id.tvStar)); + TextView tvName = (TextView) view.findViewById(R.id.label); + LinearLayout llInner = (LinearLayout) view.findViewById(R.id.llInner); + LinearLayout llButtons = (LinearLayout) view.findViewById(R.id.llButtons); + + llInner.setTag(R.string.habit_key, habit.getId()); + + helper.updateNameAndIcon(habit, tvStar, tvName); + helper.updateCheckmarkButtons(habit, llButtons); + + boolean selected = selectedPositions.contains(position); + helper.updateHabitBackground(llInner, selected); + + return view; + } + + public void setSelectedPositions(List selectedPositions) + { + this.selectedPositions = selectedPositions; + } + + public void setOnCheckmarkLongClickListener(View.OnLongClickListener listener) + { + this.onCheckmarkLongClickListener = listener; + } + + public void setOnCheckmarkClickListener(View.OnClickListener listener) + { + this.onCheckmarkClickListener = listener; + } +} diff --git a/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java b/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java index 278e54345..2268a3269 100644 --- a/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java +++ b/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java @@ -16,22 +16,11 @@ package org.isoron.uhabits.fragments; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; import android.app.Activity; -import android.app.AlertDialog; import android.app.Fragment; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; import android.content.SharedPreferences; -import android.graphics.Color; -import android.graphics.Typeface; -import android.net.Uri; -import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; -import android.util.DisplayMetrics; import android.view.ActionMode; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; @@ -46,293 +35,100 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.OnItemClickListener; -import android.widget.BaseAdapter; -import android.widget.Button; import android.widget.LinearLayout; -import android.widget.LinearLayout.LayoutParams; import android.widget.ProgressBar; import android.widget.TextView; -import com.android.colorpicker.ColorPickerDialog; -import com.android.colorpicker.ColorPickerSwatch; import com.mobeta.android.dslv.DragSortController; import com.mobeta.android.dslv.DragSortListView; import com.mobeta.android.dslv.DragSortListView.DropListener; -import org.isoron.helpers.ColorHelper; import org.isoron.helpers.Command; import org.isoron.helpers.DateHelper; import org.isoron.helpers.DialogHelper; import org.isoron.helpers.DialogHelper.OnSavedListener; import org.isoron.helpers.ReplayableActivity; import org.isoron.uhabits.R; -import org.isoron.uhabits.commands.ArchiveHabitsCommand; -import org.isoron.uhabits.commands.ChangeHabitColorCommand; -import org.isoron.uhabits.commands.DeleteHabitsCommand; import org.isoron.uhabits.commands.ToggleRepetitionCommand; -import org.isoron.uhabits.commands.UnarchiveHabitsCommand; +import org.isoron.uhabits.dialogs.HabitSelectionCallback; +import org.isoron.uhabits.dialogs.HintManager; +import org.isoron.uhabits.helpers.ListHabitsHelper; import org.isoron.uhabits.helpers.ReminderHelper; -import org.isoron.uhabits.io.CSVExporter; import org.isoron.uhabits.loaders.HabitListLoader; import org.isoron.uhabits.models.Habit; -import org.isoron.uhabits.models.Score; -import java.io.File; import java.util.Date; -import java.util.GregorianCalendar; import java.util.LinkedList; import java.util.List; public class ListHabitsFragment extends Fragment implements OnSavedListener, OnItemClickListener, OnLongClickListener, DropListener, - OnClickListener, HabitListLoader.Listener, AdapterView.OnItemLongClickListener + OnClickListener, HabitListLoader.Listener, AdapterView.OnItemLongClickListener, + HabitSelectionCallback.Listener { - private class ListHabitsActionBarCallback implements ActionMode.Callback - { - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) - { - getActivity().getMenuInflater().inflate(R.menu.list_habits_context, menu); - updateTitle(mode); - updateActions(menu); - return true; - } - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) - { - updateTitle(mode); - updateActions(menu); - return true; - } - - private void updateActions(Menu menu) - { - boolean showEdit = (selectedPositions.size() == 1); - boolean showColor = true; - boolean showArchive = true; - boolean showUnarchive = true; - - if(showEdit) showColor = false; - for(int i : selectedPositions) - { - Habit h = loader.habitsList.get(i); - if(h.isArchived()) - { - showColor = false; - showArchive = false; - } - else showUnarchive = false; - } - - MenuItem itemEdit = menu.findItem(R.id.action_edit_habit); - MenuItem itemColor = menu.findItem(R.id.action_color); - MenuItem itemArchive = menu.findItem(R.id.action_archive_habit); - MenuItem itemUnarchive = menu.findItem(R.id.action_unarchive_habit); - - itemEdit.setVisible(showEdit); - itemColor.setVisible(showColor); - itemArchive.setVisible(showArchive); - itemUnarchive.setVisible(showUnarchive); - } - - private void updateTitle(ActionMode mode) - { - mode.setTitle("" + selectedPositions.size()); - } - - @Override - public boolean onActionItemClicked(final ActionMode mode, MenuItem item) - { - final LinkedList selectedHabits = new LinkedList<>(); - for(int i : selectedPositions) - selectedHabits.add(loader.habitsList.get(i)); - - Habit firstHabit = selectedHabits.getFirst(); - - switch(item.getItemId()) - { - case R.id.action_archive_habit: - executeCommand(new ArchiveHabitsCommand(selectedHabits), null); - mode.finish(); - return true; - - case R.id.action_unarchive_habit: - executeCommand(new UnarchiveHabitsCommand(selectedHabits), null); - mode.finish(); - return true; - - case R.id.action_edit_habit: - { - EditHabitFragment frag = EditHabitFragment.editSingleHabitFragment(firstHabit.getId()); - frag.setOnSavedListener(ListHabitsFragment.this); - frag.show(getFragmentManager(), "dialog"); - return true; - } - - case R.id.action_color: - { - ColorPickerDialog picker = ColorPickerDialog.newInstance( - R.string.color_picker_default_title, ColorHelper.palette, - firstHabit.color, 4, ColorPickerDialog.SIZE_SMALL); - - picker.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener() - { - public void onColorSelected(int color) - { - executeCommand(new ChangeHabitColorCommand(selectedHabits, color), null); - mode.finish(); - } - }); - picker.show(getFragmentManager(), "picker"); - return true; - } - - case R.id.action_delete: - { - new AlertDialog.Builder(activity) - .setTitle(R.string.delete_habits) - .setMessage(R.string.delete_habits_message) - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() - { - @Override - public void onClick(DialogInterface dialog, int which) - { - executeCommand(new DeleteHabitsCommand(selectedHabits), null); - mode.finish(); - } - }).setNegativeButton(android.R.string.no, null) - .show(); - - return true; - } - - case R.id.action_export_csv: - { - onExportHabitsClick(selectedHabits); - return true; - } - } - - return false; - } - - @Override - public void onDestroyActionMode(ActionMode mode) - { - actionMode = null; - - selectedPositions.clear(); - adapter.notifyDataSetChanged(); - - listView.setDragEnabled(true); - } - } - - public static final int INACTIVE_COLOR = Color.rgb(200, 200, 200); - public static final int INACTIVE_CHECKMARK_COLOR = Color.rgb(230, 230, 230); - - public static final int HINT_INTERVAL = 5; - public static final int HINT_INTERVAL_OFFSET = 2; - - public interface OnHabitClickListener - { - void onHabitClicked(Habit habit); - } - - ListHabitsAdapter adapter; - DragSortListView listView; - ReplayableActivity activity; - TextView tvNameHeader; long lastLongClick = 0; - - private int tvNameWidth; - private int buttonCount; - private View llEmpty; - private View llHint; - - private OnHabitClickListener habitClickListener; private boolean isShortToggleEnabled; - - private HabitListLoader loader; private boolean showArchived; - private SharedPreferences prefs; private ActionMode actionMode; + private HabitListAdapter adapter; + private HabitListLoader loader; + private HintManager hintManager; + private ListHabitsHelper helper; private List selectedPositions; - private DragSortController dragSortController; + private OnHabitClickListener habitClickListener; + private ReplayableActivity activity; + private SharedPreferences prefs; + + private DragSortListView listView; + private LinearLayout llButtonsHeader; private ProgressBar progressBar; + private View llEmpty; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - DisplayMetrics dm = getResources().getDisplayMetrics(); - int width = (int) (dm.widthPixels / dm.density); - buttonCount = Math.max(0, (int) ((width - 160) / 42.0)); - tvNameWidth = (int) ((width - 30 - buttonCount * 42) * dm.density); + View view = inflater.inflate(R.layout.list_habits_fragment, container, false); + View llHint = view.findViewById(R.id.llHint); + TextView tvStarEmpty = (TextView) view.findViewById(R.id.tvStarEmpty); + listView = (DragSortListView) view.findViewById(R.id.listView); + llButtonsHeader = (LinearLayout) view.findViewById(R.id.llButtonsHeader); + llEmpty = view.findViewById(R.id.llEmpty); + progressBar = (ProgressBar) view.findViewById(R.id.progressBar); + selectedPositions = new LinkedList<>(); loader = new HabitListLoader(); + helper = new ListHabitsHelper(activity, loader); + hintManager = new HintManager(activity, llHint); + loader.setListener(this); - loader.setCheckmarkCount(buttonCount); + loader.setCheckmarkCount(helper.getButtonCount()); + loader.setProgressBar(progressBar); - View view = inflater.inflate(R.layout.list_habits_fragment, container, false); - tvNameHeader = (TextView) view.findViewById(R.id.tvNameHeader); + llHint.setOnClickListener(this); + tvStarEmpty.setTypeface(helper.getFontawesome()); - progressBar = (ProgressBar) view.findViewById(R.id.progressBar); - loader.setProgressBar(progressBar); + adapter = new HabitListAdapter(getActivity(), loader); + adapter.setSelectedPositions(selectedPositions); + adapter.setOnCheckmarkClickListener(this); + adapter.setOnCheckmarkLongClickListener(this); + + DragSortListView.DragListener dragListener = new HabitsDragListener(); + DragSortController dragSortController = new HabitsDragSortController(); - adapter = new ListHabitsAdapter(getActivity()); - listView = (DragSortListView) view.findViewById(R.id.listView); listView.setAdapter(adapter); listView.setOnItemClickListener(this); listView.setOnItemLongClickListener(this); listView.setDropListener(this); - listView.setDragListener(new DragSortListView.DragListener() - { - @Override - public void drag(int from, int to) - { - } - - @Override - public void startDrag(int position) - { - selectItem(position); - } - }); - - dragSortController = new DragSortController(listView) { - @Override - public View onCreateFloatView(int position) - { - return adapter.getView(position, null, null); - } - - @Override - public void onDestroyFloatView(View floatView) - { - } - }; - dragSortController.setRemoveEnabled(false); - + listView.setDragListener(dragListener); listView.setFloatViewManager(dragSortController); listView.setDragEnabled(true); listView.setLongClickable(true); - llHint = view.findViewById(R.id.llHint); - llHint.setOnClickListener(this); - - Typeface fontawesome = Typeface.createFromAsset(getActivity().getAssets(), - "fontawesome-webfont.ttf"); - ((TextView) view.findViewById(R.id.tvStarEmpty)).setTypeface(fontawesome); - llEmpty = view.findViewById(R.id.llEmpty); - loader.updateAllHabits(true); setHasOptionsMenu(true); - selectedPositions = new LinkedList<>(); - return view; } @@ -356,42 +152,19 @@ public class ListHabitsFragment extends Fragment if (timestamp != null && timestamp != DateHelper.getStartOfToday()) loader.updateAllHabits(true); - updateEmptyMessage(); - updateHeader(); - showNextHint(); + helper.updateEmptyMessage(llEmpty); + helper.updateHeader(llButtonsHeader); + hintManager.showHintIfAppropriate(); adapter.notifyDataSetChanged(); isShortToggleEnabled = prefs.getBoolean("pref_short_toggle", false); } - private void updateHeader() - { - LayoutInflater inflater = activity.getLayoutInflater(); - View view = getView(); - - if (view == null) return; - - GregorianCalendar day = DateHelper.getStartOfTodayCalendar(); - - LinearLayout llButtonsHeader = (LinearLayout) view.findViewById(R.id.llButtonsHeader); - llButtonsHeader.removeAllViews(); - - for (int i = 0; i < buttonCount; i++) - { - View tvDay = inflater.inflate(R.layout.list_habits_header_check, null); - Button btCheck = (Button) tvDay.findViewById(R.id.tvCheck); - btCheck.setText(DateHelper.formatHeaderDate(day)); - llButtonsHeader.addView(tvDay); - - day.add(GregorianCalendar.DAY_OF_MONTH, -1); - } - } - @Override public void onLoadFinished() { adapter.notifyDataSetChanged(); - updateEmptyMessage(); + helper.updateEmptyMessage(llEmpty); } @Override @@ -485,8 +258,13 @@ public class ListHabitsFragment extends Fragment if(actionMode == null) { - actionMode = getActivity().startActionMode(new ListHabitsActionBarCallback()); -// listView.setDragEnabled(false); + HabitSelectionCallback callback = new HabitSelectionCallback(activity, loader); + callback.setSelectedPositions(selectedPositions); + callback.setProgressBar(progressBar); + callback.setOnSavedListener(this); + callback.setListener(this); + + actionMode = getActivity().startActionMode(callback); } if(actionMode != null) actionMode.invalidate(); @@ -506,12 +284,6 @@ public class ListHabitsFragment extends Fragment if(actionMode != null) actionMode.finish(); } - private void updateEmptyMessage() - { - if (loader.getLastLoadTimestamp() == null) llEmpty.setVisibility(View.GONE); - else llEmpty.setVisibility(loader.habits.size() > 0 ? View.GONE : View.VISIBLE); - } - @Override public boolean onLongClick(View v) { @@ -538,15 +310,14 @@ public class ListHabitsFragment extends Fragment private void toggleCheck(View v) { Long tag = (Long) v.getTag(R.string.habit_key); - Habit habit = loader.habits.get(tag); - - int offset = (Integer) v.getTag(R.string.offset_key); + Integer offset = (Integer) v.getTag(R.string.offset_key); long timestamp = DateHelper.getStartOfDay( DateHelper.getLocalTime() - offset * DateHelper.millisecondsInOneDay); - if (v.getTag(R.string.toggle_key).equals(2)) updateCheckmark(habit.color, (TextView) v, 0); - else updateCheckmark(habit.color, (TextView) v, 2); + Habit habit = loader.habits.get(tag); + if(habit == null) return; + helper.toggleCheckmarkView(v, habit); executeCommand(new ToggleRepetitionCommand(habit, timestamp), habit.getId()); } @@ -555,43 +326,6 @@ public class ListHabitsFragment extends Fragment activity.executeCommand(c, refreshKey); } - private void hideHint() - { - llHint.animate().alpha(0f).setDuration(500).setListener(new AnimatorListenerAdapter() - { - @Override - public void onAnimationEnd(Animator animation) - { - llHint.setVisibility(View.GONE); - } - }); - } - - private void showNextHint() - { - Integer lastHintNumber = prefs.getInt("last_hint_number", -1); - Long lastHintTimestamp = prefs.getLong("last_hint_timestamp", -1); - - if(DateHelper.getStartOfToday() > lastHintTimestamp) - showHint(lastHintNumber + 1); - } - - private void showHint(int hintNumber) - { - String[] hints = activity.getResources().getStringArray(R.array.hints); - if(hintNumber >= hints.length) return; - - prefs.edit().putInt("last_hint_number", hintNumber).apply(); - prefs.edit().putLong("last_hint_timestamp", DateHelper.getStartOfToday()).apply(); - - TextView tvContent = (TextView) llHint.findViewById(R.id.hintContent); - tvContent.setText(hints[hintNumber]); - - llHint.setAlpha(0.0f); - llHint.setVisibility(View.VISIBLE); - llHint.animate().alpha(1f).setDuration(500); - } - @Override public void drop(int from, int to) { @@ -614,226 +348,61 @@ public class ListHabitsFragment extends Fragment break; case R.id.llHint: - hideHint(); + hintManager.dismissHint(); break; } } - class ListHabitsAdapter extends BaseAdapter + public void onPostExecuteCommand(Long refreshKey) { - private LayoutInflater inflater; - private Typeface fontawesome; - - public ListHabitsAdapter(Context context) - { + if (refreshKey == null) loader.updateAllHabits(true); + else loader.updateHabit(refreshKey); + } - inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - fontawesome = Typeface.createFromAsset(context.getAssets(), "fontawesome-webfont.ttf"); - } + public void onActionModeDestroyed(ActionMode mode) + { + actionMode = null; + selectedPositions.clear(); + adapter.notifyDataSetChanged(); + listView.setDragEnabled(true); + } - @Override - public int getCount() - { - return loader.habits.size(); - } + public interface OnHabitClickListener + { + void onHabitClicked(Habit habit); + } - @Override - public Object getItem(int position) + private class HabitsDragSortController extends DragSortController + { + public HabitsDragSortController() { - return loader.habitsList.get(position); + super(ListHabitsFragment.this.listView); + setRemoveEnabled(false); } @Override - public long getItemId(int position) + public View onCreateFloatView(int position) { - return ((Habit) getItem(position)).getId(); + return adapter.getView(position, null, null); } @Override - public View getView(int position, View view, ViewGroup parent) - { - final Habit habit = loader.habitsList.get(position); - - if (view == null || - (Long) view.getTag(R.id.timestamp_key) != DateHelper.getStartOfToday()) - { - view = inflater.inflate(R.layout.list_habits_item, null); - ((TextView) view.findViewById(R.id.tvStar)).setTypeface(fontawesome); - - LinearLayout.LayoutParams params = - new LinearLayout.LayoutParams(tvNameWidth, LayoutParams.WRAP_CONTENT, 1); - view.findViewById(R.id.label).setLayoutParams(params); - - inflateCheckmarkButtons(view); - - view.setTag(R.id.timestamp_key, DateHelper.getStartOfToday()); - } - - TextView tvStar = ((TextView) view.findViewById(R.id.tvStar)); - TextView tvName = (TextView) view.findViewById(R.id.label); - LinearLayout llInner = (LinearLayout) view.findViewById(R.id.llInner); - LinearLayout llButtons = (LinearLayout) view.findViewById(R.id.llButtons); - - llInner.setTag(R.string.habit_key, habit.getId()); - - updateNameAndIcon(habit, tvStar, tvName); - updateCheckmarkButtons(habit, llButtons); - - boolean selected = selectedPositions.contains(position); - if(selected) - llInner.setBackgroundResource(R.drawable.selected_box); - else - { - if (android.os.Build.VERSION.SDK_INT >= 21) - llInner.setBackgroundResource(R.drawable.ripple_white); - else - llInner.setBackgroundResource(R.drawable.card_background); - } - - return view; - } - - private void inflateCheckmarkButtons(View view) - { - for (int i = 0; i < buttonCount; i++) - { - View check = inflater.inflate(R.layout.list_habits_item_check, null); - TextView btCheck = (TextView) check.findViewById(R.id.tvCheck); - btCheck.setTypeface(fontawesome); - btCheck.setOnLongClickListener(ListHabitsFragment.this); - btCheck.setOnClickListener(ListHabitsFragment.this); - ((LinearLayout) view.findViewById(R.id.llButtons)).addView(check); - } - } - } - - private void updateCheckmarkButtons(Habit habit, LinearLayout llButtons) - { - int activeColor = getActiveColor(habit); - int m = llButtons.getChildCount(); - Long habitId = habit.getId(); - - int isChecked[] = loader.checkmarks.get(habitId); - - for (int i = 0; i < m; i++) + public void onDestroyFloatView(View floatView) { - - TextView tvCheck = (TextView) llButtons.getChildAt(i); - tvCheck.setTag(R.string.habit_key, habitId); - tvCheck.setTag(R.string.offset_key, i); - if(isChecked.length > i) - updateCheckmark(activeColor, tvCheck, isChecked[i]); } } - private void updateNameAndIcon(Habit habit, TextView tvStar, TextView tvName) + private class HabitsDragListener implements DragSortListView.DragListener { - int activeColor = getActiveColor(habit); - - tvName.setText(habit.name); - tvName.setTextColor(activeColor); - - if (habit.isArchived()) + @Override + public void drag(int from, int to) { - tvStar.setText(getString(R.string.fa_archive)); - tvStar.setTextColor(activeColor); } - else - { - int score = loader.scores.get(habit.getId()); - if (score < Score.HALF_STAR_CUTOFF) - { - tvStar.setText(getString(R.string.fa_star_o)); - tvStar.setTextColor(INACTIVE_COLOR); - } - else if (score < Score.FULL_STAR_CUTOFF) - { - tvStar.setText(getString(R.string.fa_star_half_o)); - tvStar.setTextColor(INACTIVE_COLOR); - } - else - { - tvStar.setText(getString(R.string.fa_star)); - tvStar.setTextColor(activeColor); - } - } - } - - private int getActiveColor(Habit habit) - { - int activeColor = habit.color; - if(habit.isArchived()) activeColor = INACTIVE_COLOR; - - return activeColor; - } - - private void updateCheckmark(int activeColor, TextView tvCheck, int check) - { - switch (check) + @Override + public void startDrag(int position) { - case 2: - tvCheck.setText(R.string.fa_check); - tvCheck.setTextColor(activeColor); - tvCheck.setTag(R.string.toggle_key, 2); - break; - - case 1: - tvCheck.setText(R.string.fa_check); - tvCheck.setTextColor(INACTIVE_CHECKMARK_COLOR); - tvCheck.setTag(R.string.toggle_key, 1); - break; - - case 0: - tvCheck.setText(R.string.fa_times); - tvCheck.setTextColor(INACTIVE_CHECKMARK_COLOR); - tvCheck.setTag(R.string.toggle_key, 0); - break; + selectItem(position); } } - - public void onPostExecuteCommand(Long refreshKey) - { - if (refreshKey == null) loader.updateAllHabits(true); - else loader.updateHabit(refreshKey); - } - - private void onExportHabitsClick(final LinkedList selectedHabits) - { - new AsyncTask() - { - String filename; - - @Override - protected void onPreExecute() - { - progressBar.setIndeterminate(true); - progressBar.setVisibility(View.VISIBLE); - } - - @Override - protected void onPostExecute(Void aVoid) - { - if(filename != null) - { - Intent intent = new Intent(); - intent.setAction(Intent.ACTION_SEND); - intent.setType("application/zip"); - intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(filename))); - - startActivity(intent); - } - - progressBar.setVisibility(View.GONE); - } - - @Override - protected Void doInBackground(Void... params) - { - CSVExporter exporter = new CSVExporter(activity, selectedHabits); - filename = exporter.writeArchive(); - return null; - } - }.execute(); - } } diff --git a/app/src/main/java/org/isoron/uhabits/helpers/ListHabitsHelper.java b/app/src/main/java/org/isoron/uhabits/helpers/ListHabitsHelper.java new file mode 100644 index 000000000..e06015db7 --- /dev/null +++ b/app/src/main/java/org/isoron/uhabits/helpers/ListHabitsHelper.java @@ -0,0 +1,211 @@ +package org.isoron.uhabits.helpers; + +import android.content.Context; +import android.graphics.Color; +import android.graphics.Typeface; +import android.util.DisplayMetrics; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.isoron.helpers.DateHelper; +import org.isoron.uhabits.R; +import org.isoron.uhabits.loaders.HabitListLoader; +import org.isoron.uhabits.models.Habit; +import org.isoron.uhabits.models.Score; + +import java.util.GregorianCalendar; + +public class ListHabitsHelper +{ + public static final int INACTIVE_COLOR = Color.rgb(200, 200, 200); + public static final int INACTIVE_CHECKMARK_COLOR = Color.rgb(230, 230, 230); + + private final Context context; + private final HabitListLoader loader; + private Typeface fontawesome; + + public ListHabitsHelper(Context context, HabitListLoader loader) + { + this.context = context; + this.loader = loader; + + fontawesome = Typeface.createFromAsset(context.getAssets(), "fontawesome-webfont.ttf"); + } + + public Typeface getFontawesome() + { + return fontawesome; + } + + public int getButtonCount() + { + DisplayMetrics dm = context.getResources().getDisplayMetrics(); + int width = (int) (dm.widthPixels / dm.density); + return Math.max(0, (int) ((width - 160) / 42.0)); + } + + public int getHabitNameWidth() + { + DisplayMetrics dm = context.getResources().getDisplayMetrics(); + int width = (int) (dm.widthPixels / dm.density); + return (int) ((width - 30 - getButtonCount() * 42) * dm.density); + } + + public void updateCheckmarkButtons(Habit habit, LinearLayout llButtons) + { + int activeColor = getActiveColor(habit); + int m = llButtons.getChildCount(); + Long habitId = habit.getId(); + + int isChecked[] = loader.checkmarks.get(habitId); + + for (int i = 0; i < m; i++) + { + + TextView tvCheck = (TextView) llButtons.getChildAt(i); + tvCheck.setTag(R.string.habit_key, habitId); + tvCheck.setTag(R.string.offset_key, i); + if(isChecked.length > i) + updateCheckmark(activeColor, tvCheck, isChecked[i]); + } + } + + public int getActiveColor(Habit habit) + { + int activeColor = habit.color; + if(habit.isArchived()) activeColor = INACTIVE_COLOR; + + return activeColor; + } + + public void initializeLabelAndIcon(View itemView) + { + TextView tvStar = (TextView) itemView.findViewById(R.id.tvStar); + tvStar.setTypeface(getFontawesome()); + + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(getHabitNameWidth(), + LinearLayout.LayoutParams.WRAP_CONTENT, 1); + itemView.findViewById(R.id.label).setLayoutParams(params); + } + + public void updateNameAndIcon(Habit habit, TextView tvStar, TextView tvName) + { + int activeColor = getActiveColor(habit); + + tvName.setText(habit.name); + tvName.setTextColor(activeColor); + + if (habit.isArchived()) + { + tvStar.setText(context.getString(R.string.fa_archive)); + tvStar.setTextColor(activeColor); + } + else + { + int score = loader.scores.get(habit.getId()); + + if (score < Score.HALF_STAR_CUTOFF) + { + tvStar.setText(context.getString(R.string.fa_star_o)); + tvStar.setTextColor(INACTIVE_COLOR); + } + else if (score < Score.FULL_STAR_CUTOFF) + { + tvStar.setText(context.getString(R.string.fa_star_half_o)); + tvStar.setTextColor(INACTIVE_COLOR); + } + else + { + tvStar.setText(context.getString(R.string.fa_star)); + tvStar.setTextColor(activeColor); + } + } + } + + public void updateCheckmark(int activeColor, TextView tvCheck, int check) + { + switch (check) + { + case 2: + tvCheck.setText(R.string.fa_check); + tvCheck.setTextColor(activeColor); + tvCheck.setTag(R.string.toggle_key, 2); + break; + + case 1: + tvCheck.setText(R.string.fa_check); + tvCheck.setTextColor(INACTIVE_CHECKMARK_COLOR); + tvCheck.setTag(R.string.toggle_key, 1); + break; + + case 0: + tvCheck.setText(R.string.fa_times); + tvCheck.setTextColor(INACTIVE_CHECKMARK_COLOR); + tvCheck.setTag(R.string.toggle_key, 0); + break; + } + } + + public void updateHabitBackground(View view, boolean isSelected) + { + if (isSelected) + view.setBackgroundResource(R.drawable.selected_box); + else + { + if (android.os.Build.VERSION.SDK_INT >= 21) + view.setBackgroundResource(R.drawable.ripple_white); + else view.setBackgroundResource(R.drawable.card_background); + } + } + + public void inflateCheckmarkButtons(View view, View.OnLongClickListener onLongClickListener, + View.OnClickListener onClickListener, LayoutInflater inflater) + { + for (int i = 0; i < getButtonCount(); i++) + { + View check = inflater.inflate(R.layout.list_habits_item_check, null); + TextView btCheck = (TextView) check.findViewById(R.id.tvCheck); + btCheck.setTypeface(fontawesome); + btCheck.setOnLongClickListener(onLongClickListener); + btCheck.setOnClickListener(onClickListener); + ((LinearLayout) view.findViewById(R.id.llButtons)).addView(check); + } + + view.setTag(R.id.timestamp_key, DateHelper.getStartOfToday()); + } + + public void updateHeader(ViewGroup header) + { + LayoutInflater inflater = LayoutInflater.from(context); + GregorianCalendar day = DateHelper.getStartOfTodayCalendar(); + header.removeAllViews(); + + for (int i = 0; i < getButtonCount(); i++) + { + View tvDay = inflater.inflate(R.layout.list_habits_header_check, null); + Button btCheck = (Button) tvDay.findViewById(R.id.tvCheck); + btCheck.setText(DateHelper.formatHeaderDate(day)); + header.addView(tvDay); + + day.add(GregorianCalendar.DAY_OF_MONTH, -1); + } + } + + public void updateEmptyMessage(View view) + { + if (loader.getLastLoadTimestamp() == null) view.setVisibility(View.GONE); + else view.setVisibility(loader.habits.size() > 0 ? View.GONE : View.VISIBLE); + } + + public void toggleCheckmarkView(View v, Habit habit) + { + if (v.getTag(R.string.toggle_key).equals(2)) + updateCheckmark(habit.color, (TextView) v, 0); + else + updateCheckmark(habit.color, (TextView) v, 2); + } +} diff --git a/app/src/main/res/values/dimens_color_picker.xml b/app/src/main/res/values/dimens_color_picker.xml deleted file mode 100644 index 27517fbae..000000000 --- a/app/src/main/res/values/dimens_color_picker.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - 64dip - 48dip - 8dip - 4dip - \ No newline at end of file diff --git a/app/src/main/res/values/dimens_date_time.xml b/app/src/main/res/values/pickers.xml similarity index 59% rename from app/src/main/res/values/dimens_date_time.xml rename to app/src/main/res/values/pickers.xml index 201590689..a515da332 100644 --- a/app/src/main/res/values/dimens_date_time.xml +++ b/app/src/main/res/values/pickers.xml @@ -1,5 +1,10 @@ - - + + + 64dip + 48dip + 8dip + 4dip + 0.82 0.85 0.16 @@ -39,4 +44,22 @@ 16sp 64dp 22dp + + Color %1$d + Color %1$d selected + + + Hours circular slider + Minutes circular slider + Month grid of days + Year list + Select month and day + Select year + %1$s selected + %1$s deleted + -- + : + sans-serif + sans-serif + sans-serif \ 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 a256b43ef..2fbf6d670 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - + Loop Habit Tracker Habits @@ -21,28 +21,6 @@ Habits archived. Habits unarchived. - Color %1$d - Color %1$d selected - - - Done - Clear - Hours circular slider - Minutes circular slider - Select hours - Select minutes - Month grid of days - Year list - Select month and day - Select year - %1$s selected - %1$s deleted - -- - : - sans-serif - sans-serif - sans-serif - Overview Habit strength @@ -111,6 +89,11 @@ Select days Export data + Done + Clear + Select hours + Select minutes + @string/hint_drag @string/hint_landscape diff --git a/app/src/main/res/values/styles_show_habit.xml b/app/src/main/res/values/styles_show_habit.xml deleted file mode 100644 index a6b3daec9..000000000 --- a/app/src/main/res/values/styles_show_habit.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file