2 * Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
6 * Privacy Browser is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Browser is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>.
20 package com.stoutner.privacybrowser.fragments;
22 import android.content.Context;
23 import android.content.SharedPreferences;
24 import android.os.Bundle;
25 import android.preference.PreferenceManager;
26 import android.view.LayoutInflater;
27 import android.view.View;
28 import android.view.ViewGroup;
29 import android.widget.AdapterView;
30 import android.widget.ListView;
32 import androidx.annotation.NonNull;
33 import androidx.fragment.app.Fragment; // The AndroidX fragment must be used until minimum API >= 23. Otherwise `getContext()` does not work.
34 import androidx.fragment.app.FragmentManager;
36 import com.google.android.material.floatingactionbutton.FloatingActionButton;
38 import com.stoutner.privacybrowser.R;
39 import com.stoutner.privacybrowser.activities.DomainsActivity;
41 public class DomainsListFragment extends Fragment {
42 // Instantiate the dismiss snackbar interface handle.
43 private DismissSnackbarInterface dismissSnackbarInterface;
45 // Define the public dismiss snackbar interface.
46 public interface DismissSnackbarInterface {
47 void dismissSnackbar();
50 public void onAttach(Context context) {
51 // Run the default commands.
52 super.onAttach(context);
54 // Get a handle for the dismiss snackbar interface.
55 dismissSnackbarInterface = (DismissSnackbarInterface) context;
58 public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
59 // Inflate `domains_list_fragment`. `false` does not attach it to the root `container`.
60 View domainsListFragmentView = inflater.inflate(R.layout.domains_list_fragment, container, false);
62 // Initialize `domainsListView`.
63 ListView domainsListView = domainsListFragmentView.findViewById(R.id.domains_listview);
65 // Remove the incorrect lint error below that `.getSupportFragmentManager()` might be null.
66 assert getActivity() != null;
68 // Get a handle for the support fragment manager.
69 final FragmentManager supportFragmentManager = getActivity().getSupportFragmentManager();
71 domainsListView.setOnItemClickListener((AdapterView<?> parent, View view, int position, long id) -> {
72 // Dismiss the snackbar if it is visible.
73 dismissSnackbarInterface.dismissSnackbar();
75 // Save the current domain settings if operating in two-paned mode and a domain is currently selected.
76 if (DomainsActivity.twoPanedMode && DomainsActivity.deleteMenuItem.isEnabled()) {
77 // Get a handle for the domain settings fragment.
78 Fragment domainSettingsFragment = supportFragmentManager.findFragmentById(R.id.domain_settings_fragment_container);
80 // Remove the incorrect lint error below that the domain settings fragment might be null.
81 assert domainSettingsFragment != null;
83 // Get a handle for the domain settings fragment view.
84 View domainSettingsFragmentView = domainSettingsFragment.getView();
86 // Get a handle for the domains activity.
87 DomainsActivity domainsActivity = new DomainsActivity();
89 // Save the domain settings.
90 domainsActivity.saveDomainSettings(domainSettingsFragmentView, getResources());
93 // Store the new `currentDomainDatabaseId`, converting it from `long` to `int` to match the format of the domains database.
94 DomainsActivity.currentDomainDatabaseId = (int) id;
96 // Add `currentDomainDatabaseId` to `argumentsBundle`.
97 Bundle argumentsBundle = new Bundle();
98 argumentsBundle.putInt(DomainSettingsFragment.DATABASE_ID, DomainsActivity.currentDomainDatabaseId);
100 // Add the arguments bundle to the domain settings fragment.
101 DomainSettingsFragment domainSettingsFragment = new DomainSettingsFragment();
102 domainSettingsFragment.setArguments(argumentsBundle);
104 // Display the domain settings fragment.
105 if (DomainsActivity.twoPanedMode) { // The device in in two-paned mode.
106 // enable `deleteMenuItem` if the system is not waiting for a `Snackbar` to be dismissed.
107 if (!DomainsActivity.dismissingSnackbar) {
108 // Enable the delete menu item.
109 DomainsActivity.deleteMenuItem.setEnabled(true);
111 // Get a handle for the shared preferences.
112 SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
114 // Get the theme preferences.
115 boolean darkTheme = sharedPreferences.getBoolean("dark_theme", false);
117 // Set the delete icon according to the theme.
119 DomainsActivity.deleteMenuItem.setIcon(R.drawable.delete_dark);
121 DomainsActivity.deleteMenuItem.setIcon(R.drawable.delete_light);
125 // Display the domain settings fragment.
126 supportFragmentManager.beginTransaction().replace(R.id.domain_settings_fragment_container, domainSettingsFragment).commit();
127 } else { // The device in in single-paned mode
128 // Show `deleteMenuItem` if the system is not waiting for a `Snackbar` to be dismissed.
129 if (!DomainsActivity.dismissingSnackbar) {
130 DomainsActivity.deleteMenuItem.setVisible(true);
133 // Hide the add domain FAB.
134 FloatingActionButton addDomainFAB = getActivity().findViewById(R.id.add_domain_fab);
137 // Display the domain settings fragment.
138 supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
142 return domainsListFragmentView;