/* * Copyright 2018 Hippo Seven * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hippo.ehviewer.ui; /* * Created by Hippo on 2018/3/23. */ import android.app.Dialog; import android.content.DialogInterface; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.util.Pair; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.textfield.TextInputLayout; import com.hippo.android.resource.AttrResources; import com.hippo.easyrecyclerview.EasyRecyclerView; import com.hippo.easyrecyclerview.LinearDividerItemDecoration; import com.hippo.ehviewer.EhApplication; import com.hippo.ehviewer.Hosts; import com.hippo.ehviewer.R; import com.hippo.ripple.Ripple; import com.hippo.yorozuya.LayoutUtils; import java.util.List; import java.util.Locale; public class HostsActivity extends ToolbarActivity implements EasyRecyclerView.OnItemClickListener, View.OnClickListener { private static final String DIALOG_TAG_ADD_HOST = AddHostDialogFragment.class.getName(); private static final String DIALOG_TAG_EDIT_HOST = EditHostDialogFragment.class.getName(); private static final String KEY_HOST = "com.hippo.ehviewer.ui.HostsActivity.HOST"; private static final String KEY_IP = "com.hippo.ehviewer.ui.HostsActivity.IP"; private Hosts hosts; private List<Pair<String, String>> data; private EasyRecyclerView recyclerView; private View tip; private HostsAdapter adapter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); hosts = EhApplication.getHosts(this); data = hosts.getAll(); setContentView(R.layout.activity_hosts); setNavigationIcon(R.drawable.v_arrow_left_dark_x24); recyclerView = findViewById(R.id.recycler_view); tip = findViewById(R.id.tip); FloatingActionButton fab = findViewById(R.id.fab); adapter = new HostsAdapter(); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false)); LinearDividerItemDecoration decoration = new LinearDividerItemDecoration( LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(this, R.attr.dividerColor), LayoutUtils.dp2pix(this, 1)); decoration.setShowLastDivider(true); recyclerView.addItemDecoration(decoration); recyclerView.setSelector(Ripple.generateRippleDrawable(this, !AttrResources.getAttrBoolean(this, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT))); recyclerView.setHasFixedSize(true); recyclerView.setOnItemClickListener(this); recyclerView.setPadding( recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(), recyclerView.getPaddingRight(), recyclerView.getPaddingBottom() + getResources().getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab)); fab.setOnClickListener(this); recyclerView.setVisibility(data.isEmpty() ? View.GONE : View.VISIBLE); tip.setVisibility(data.isEmpty() ? View.VISIBLE : View.GONE); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); return true; default: return super.onOptionsItemSelected(item); } } @Override public boolean onItemClick(EasyRecyclerView easyRecyclerView, View view, int position, long id) { Pair<String, String> pair = data.get(position); Bundle args = new Bundle(); args.putString(KEY_HOST, pair.first); args.putString(KEY_IP, pair.second); DialogFragment fragment = new EditHostDialogFragment(); fragment.setArguments(args); fragment.show(getSupportFragmentManager(), DIALOG_TAG_EDIT_HOST); return true; } @Override public void onClick(View v) { new AddHostDialogFragment().show(getSupportFragmentManager(), DIALOG_TAG_ADD_HOST); } private void notifyHostsChanges() { data = hosts.getAll(); recyclerView.setVisibility(data.isEmpty() ? View.GONE : View.VISIBLE); tip.setVisibility(data.isEmpty() ? View.VISIBLE : View.GONE); adapter.notifyDataSetChanged(); } private class HostsHolder extends RecyclerView.ViewHolder { public final TextView host; public final TextView ip; public HostsHolder(View itemView) { super(itemView); host = itemView.findViewById(R.id.host); ip = itemView.findViewById(R.id.ip); } } private class HostsAdapter extends RecyclerView.Adapter<HostsHolder> { private final LayoutInflater inflater = getLayoutInflater(); @NonNull @Override public HostsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new HostsHolder(inflater.inflate(R.layout.item_hosts, parent, false)); } @Override public void onBindViewHolder(@NonNull HostsHolder holder, int position) { Pair<String, String> pair = data.get(position); holder.host.setText(pair.first); holder.ip.setText(pair.second); } @Override public int getItemCount() { return data.size(); } } public abstract static class HostDialogFragment extends DialogFragment { private TextView host; private TextView ip; @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_hosts, null, false); host = view.findViewById(R.id.host); ip = view.findViewById(R.id.ip); Bundle arguments = getArguments(); if (savedInstanceState == null && arguments != null) { host.setText(arguments.getString(KEY_HOST)); ip.setText(arguments.getString(KEY_IP)); } AlertDialog.Builder builder = new AlertDialog.Builder(getContext()).setView(view); onCreateDialogBuilder(builder); AlertDialog dialog = builder.create(); dialog.setOnShowListener(d -> onCreateDialog((AlertDialog) d)); return dialog; } protected abstract void onCreateDialogBuilder(AlertDialog.Builder builder); protected abstract void onCreateDialog(AlertDialog dialog); protected void put(AlertDialog dialog) { TextView host = dialog.findViewById(R.id.host); TextView ip = dialog.findViewById(R.id.ip); String hostString = host.getText().toString().trim().toLowerCase(Locale.US); String ipString = ip.getText().toString().trim(); if (!Hosts.isValidHost(hostString)) { TextInputLayout hostInputLayout = dialog.findViewById(R.id.host_input_layout); hostInputLayout.setError(getContext().getString(R.string.invalid_host)); return; } if (!Hosts.isValidIp(ipString)) { TextInputLayout ipInputLayout = dialog.findViewById(R.id.ip_input_layout); ipInputLayout.setError(getContext().getString(R.string.invalid_ip)); return; } HostsActivity activity = (HostsActivity) dialog.getOwnerActivity(); activity.hosts.put(hostString, ipString); activity.notifyHostsChanges(); dialog.dismiss(); } protected void delete(AlertDialog dialog) { TextView host = dialog.findViewById(R.id.host); String hostString = host.getText().toString().trim().toLowerCase(Locale.US); HostsActivity activity = (HostsActivity) dialog.getOwnerActivity(); activity.hosts.delete(hostString); activity.notifyHostsChanges(); dialog.dismiss(); } } public static class AddHostDialogFragment extends HostDialogFragment { @Override protected void onCreateDialogBuilder(AlertDialog.Builder builder) { builder.setTitle(R.string.add_host); builder.setPositiveButton(R.string.add_host_add, null); } @Override protected void onCreateDialog(AlertDialog dialog) { dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v -> put(dialog)); } } public static class EditHostDialogFragment extends HostDialogFragment { @Override protected void onCreateDialogBuilder(AlertDialog.Builder builder) { builder.setTitle(R.string.edit_host); builder.setPositiveButton(R.string.edit_host_confirm, null); builder.setNegativeButton(R.string.edit_host_delete, null); } @Override protected void onCreateDialog(AlertDialog dialog) { dialog.findViewById(R.id.host_input_layout).setEnabled(false); dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v -> put(dialog)); dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setOnClickListener(v -> delete(dialog)); } } }