MainActivity.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. package com.noahvogt.miniprojekt;
  2. import android.content.Context;
  3. import android.content.DialogInterface;
  4. import android.content.Intent;
  5. import android.content.SharedPreferences;
  6. import android.os.Bundle;
  7. import android.view.Menu;
  8. import android.view.View;
  9. import android.widget.Button;
  10. import android.widget.EditText;
  11. import android.widget.Toast;
  12. import androidx.appcompat.app.AlertDialog;
  13. import androidx.appcompat.app.AppCompatActivity;
  14. import androidx.appcompat.widget.Toolbar;
  15. import androidx.drawerlayout.widget.DrawerLayout;
  16. import androidx.fragment.app.DialogFragment;
  17. import com.google.android.material.dialog.MaterialAlertDialogBuilder;
  18. import com.google.android.material.floatingactionbutton.FloatingActionButton;
  19. import com.google.gson.GsonBuilder;
  20. import com.google.gson.reflect.TypeToken;
  21. import com.noahvogt.miniprojekt.DataBase.Message;
  22. import androidx.fragment.app.Fragment;
  23. import androidx.fragment.app.FragmentManager;
  24. import androidx.lifecycle.ViewModelProvider;
  25. import androidx.recyclerview.widget.LinearLayoutManager;
  26. import androidx.recyclerview.widget.RecyclerView;
  27. import com.google.android.material.navigation.NavigationView;
  28. import androidx.navigation.NavController;
  29. import androidx.navigation.Navigation;
  30. import androidx.navigation.ui.AppBarConfiguration;
  31. import androidx.navigation.ui.NavigationUI;
  32. import com.chaquo.python.Python;
  33. import com.chaquo.python.android.AndroidPlatform;
  34. import com.google.android.material.snackbar.Snackbar;
  35. import com.noahvogt.miniprojekt.data.CustomAdapter;
  36. import com.noahvogt.miniprojekt.data.EmailViewModel;
  37. import com.noahvogt.miniprojekt.data.MailFunctions;
  38. import com.noahvogt.miniprojekt.data.ReadInMailsActivity;
  39. import com.noahvogt.miniprojekt.ui.show.MessageShowFragment;
  40. import com.noahvogt.miniprojekt.data.BooleanTypeAdapter;
  41. import java.lang.reflect.Type;
  42. import java.text.SimpleDateFormat;
  43. import java.util.ArrayList;
  44. import java.util.Date;
  45. import java.util.HashSet;
  46. import java.util.List;
  47. import java.util.Set;
  48. import com.google.gson.Gson;
  49. import static com.noahvogt.miniprojekt.R.id.drawer_layout;
  50. public class MainActivity extends AppCompatActivity implements View.OnClickListener, CustomAdapter.SelectedMessage {
  51. private AppBarConfiguration mAppBarConfiguration;
  52. public static final int NEW_WORD_ACTIVITY_REQUEST_CODE = 1;
  53. public static EmailViewModel mEmailViewModel;
  54. public static RecyclerView recyclerView;
  55. private AlertDialog dialog;
  56. private EditText newemail_name, newemail_email, newemail_password; /* may not be private */
  57. SharedPreferences preferences, mailServerCredentials;
  58. /* leave descriptor empty */
  59. public MainActivity() {}
  60. public String getVisibleFragment(){
  61. FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
  62. List<Fragment> fragments = fragmentManager.getFragments();
  63. if(fragments != null){
  64. showToast("not null");
  65. for(Fragment fragment : fragments){
  66. showToast(fragment.toString());
  67. if(fragment.isVisible())
  68. showToast("found visible fragment");
  69. return "is gallery";
  70. }
  71. } else {
  72. showToast("null");}
  73. return null;
  74. }
  75. @Override
  76. protected void onCreate(Bundle savedInstanceState) {
  77. super.onCreate(savedInstanceState);
  78. setContentView(R.layout.activity_main);
  79. /* define button listeners */
  80. Button add_email_button = (Button) findViewById(R.id.addEmailButton);
  81. add_email_button.setOnClickListener(new View.OnClickListener() {
  82. @Override
  83. public void onClick(View v) {
  84. createNewEmailDialog();
  85. }
  86. });
  87. /*creates accountmanager by clicking on profil */
  88. View accountView = findViewById(R.id.accountView);
  89. accountView.setOnClickListener(new View.OnClickListener() {
  90. @Override
  91. public void onClick(View v) {
  92. createNewEmailDialog();
  93. }
  94. });
  95. /* invoke preferences */
  96. preferences = getSharedPreferences("UserPreferences", Context.MODE_PRIVATE);
  97. mailServerCredentials = getSharedPreferences("Credentials", Context.MODE_PRIVATE);
  98. /* invoke toolbar */
  99. Toolbar toolbar = findViewById(R.id.toolbar);
  100. setSupportActionBar(toolbar);
  101. /* invoke drawer */
  102. DrawerLayout drawer = findViewById(drawer_layout);
  103. NavigationView navigationView = findViewById(R.id.nav_view);
  104. /*
  105. Passing each menu ID as a set of Ids because each
  106. menu should be considered as top level destinations.
  107. */
  108. mAppBarConfiguration = new AppBarConfiguration.Builder(
  109. R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow, R.id.nav_archive, R.id.nav_spam)
  110. .setDrawerLayout(drawer)
  111. .build();
  112. NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
  113. NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
  114. NavigationUI.setupWithNavController(navigationView, navController);
  115. /* Lookup the recyclerview in activity layout */
  116. recyclerView = findViewById(R.id.recyclerView);
  117. final CustomAdapter adapter = new CustomAdapter(new CustomAdapter.EmailDiff(),this);
  118. /* Attach the adapter to the recyclerview to populate items */
  119. recyclerView.setAdapter(adapter);
  120. recyclerView.setLayoutManager(new LinearLayoutManager(this));
  121. /* get Inbox Messages in Recyclerviewer at begining is overwritten by Fragments but has to stay*/
  122. mEmailViewModel = new ViewModelProvider(this).get(EmailViewModel.class);
  123. mEmailViewModel.getInboxMessage().observe(this, messages -> {
  124. /* Update the cached copy of the messages in the adapter*/
  125. adapter.submitList(messages);
  126. });
  127. Button settingButton = findViewById(R.id.settingsButton);
  128. settingButton.setOnClickListener(new View.OnClickListener() {
  129. @Override
  130. public void onClick(View v) {
  131. Intent i = new Intent(MainActivity.this, SettingsActivity.class);
  132. startActivity(i);
  133. }
  134. });
  135. /* Start email Writer*/
  136. FloatingActionButton message_create_button = findViewById(R.id.messageButton);
  137. message_create_button.setOnClickListener(new View.OnClickListener() {
  138. @Override
  139. public void onClick(View v) {
  140. DialogFragment dialog = MessageCreateFragment.newInstance();
  141. dialog.show(getSupportFragmentManager(), "tag");
  142. }
  143. });
  144. /* start python instance right on startup */
  145. if (! Python.isStarted()) {
  146. Python.start(new AndroidPlatform(this));
  147. }
  148. }
  149. /* gets the data from the Email writer and adds it to the Database */
  150. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  151. super.onActivityResult(requestCode, resultCode, MessageCreateFragment.replyIntent);
  152. /* Creates class for the Date when Email is written */
  153. Date dNow = new Date();
  154. SimpleDateFormat ft =
  155. new SimpleDateFormat("dd.MM.yy");
  156. System.out.println(dNow);
  157. // if (requestCode == NEW_WORD_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
  158. Message word = new Message(
  159. MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.EXTRA_TO),
  160. null,
  161. null,
  162. MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.EXTRA_FROM),
  163. ft.format(dNow),
  164. MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.EXTRA_SUBJECT),
  165. MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.EXTRA_MESSAGE),
  166. "Draft",false);
  167. mEmailViewModel.insert(word);
  168. }
  169. @Override
  170. public boolean onCreateOptionsMenu(Menu menu) {
  171. /* Inflate the menu; this adds items to the action bar if it is present. */
  172. getMenuInflater().inflate(R.menu.main, menu);
  173. return true;
  174. }
  175. @Override
  176. public boolean onSupportNavigateUp() {
  177. NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
  178. return NavigationUI.navigateUp(navController, mAppBarConfiguration)
  179. || super.onSupportNavigateUp();
  180. }
  181. /* better leave empty to avoid any listener disambiguity */
  182. public void onClick(View view) { }
  183. public void changeMailServerSettingsDialog(String name, String email, String password) {
  184. /* define View window */
  185. AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
  186. final View changeMailServerSettingsView = getLayoutInflater().inflate(R.layout.mail_credentials_customizer, null);
  187. EditText incomingServerObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_incoming_server_text);
  188. EditText outgoingServerObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_outgoing_server_text);
  189. EditText incomingPortObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_incoming_port_text);
  190. EditText outgoingPortObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_outgoing_port_text);
  191. EditText serverUsernameObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_username_text);
  192. EditText passwordObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_password_text);
  193. /* set assumed input in corresponding fields */
  194. incomingServerObject.setText(MailFunctions.getImapHostFromEmail(email));
  195. outgoingServerObject.setText(MailFunctions.getSmtpHostFromEmail(email));
  196. incomingPortObject.setText("993");
  197. outgoingPortObject.setText("587");
  198. serverUsernameObject.setText(email);
  199. passwordObject.setText(password);
  200. /* TODO: add save and cancel button functionality */
  201. /* open View window */
  202. dialogBuilder.setView(changeMailServerSettingsView);
  203. dialog = dialogBuilder.create();
  204. dialog.show();
  205. }
  206. public void askForChangeMailServerSettingsDialog(String name, String email, String password) {
  207. /* define View window */
  208. AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
  209. /* open View window */
  210. dialogBuilder.setTitle("failed to connect :(");
  211. dialogBuilder
  212. .setMessage("Do you want to further customize your mail server settings?")
  213. .setPositiveButton("Yes",new DialogInterface.OnClickListener() {
  214. public void onClick(DialogInterface dialog, int id) {
  215. /*if this button is clicked, close the whole fragment */
  216. changeMailServerSettingsDialog(name, email, password);
  217. }
  218. })
  219. .setNegativeButton("No",new DialogInterface.OnClickListener() {
  220. public void onClick(DialogInterface dialog,int id) {
  221. /* if this button is clicked, close the hole fragment */
  222. dialog.dismiss();
  223. }
  224. });
  225. dialog = dialogBuilder.create();
  226. dialog.show();
  227. }
  228. public void createNewEmailDialog(){
  229. /* define View window */
  230. AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
  231. final View emailPopupView = getLayoutInflater().inflate(R.layout.popup, null);
  232. /* init text field variables */
  233. newemail_name = emailPopupView.findViewById(R.id.popup_material_name_asking_text);
  234. newemail_email = emailPopupView.findViewById(R.id.popup_material_email_asking_text);
  235. newemail_password = emailPopupView.findViewById(R.id.popup_material_password_asking_text);
  236. /* init button variables */
  237. Button newemail_save_button = (Button) emailPopupView.findViewById(R.id.saveButton);
  238. /* may not be private */
  239. Button newemail_cancel_button = (Button) emailPopupView.findViewById(R.id.cancelButton);
  240. /* open View window */
  241. dialogBuilder.setView(emailPopupView);
  242. dialog = dialogBuilder.create();
  243. dialog.show();
  244. SharedPreferences.Editor preferencesEditor = preferences.edit();
  245. SharedPreferences.Editor credentialsEditor = mailServerCredentials.edit();
  246. if (! Python.isStarted()) {
  247. Python.start(new AndroidPlatform(this));
  248. }
  249. /* store user input */
  250. newemail_save_button.setOnClickListener(new View.OnClickListener() {
  251. @Override
  252. public void onClick(View v) {
  253. /* store user input */
  254. String name = newemail_name.getText().toString();
  255. String email = newemail_email.getText().toString();
  256. String password = newemail_password.getText().toString();
  257. if (!MailFunctions.validateEmail(newemail_email) | !MailFunctions.validateName(newemail_name) |
  258. !MailFunctions.validatePassword(newemail_password)) {
  259. return;
  260. }
  261. /* connect to mail server */
  262. showToast("Probe Connection ...");
  263. if (MailFunctions.canConnect(MailFunctions.getImapHostFromEmail(email), email, password) == Boolean.TRUE) {
  264. showToast("was able to connect");
  265. // Intent intent = new Intent(getBaseContext(), ReadInMailsActivity.class);
  266. // intent.putExtra("Email", email);
  267. // intent.putExtra("Password", password);
  268. // startActivity(intent);
  269. // startActivityForResult(intent, MainActivity.NEW_WORD_ACTIVITY_REQUEST_CODE);
  270. /* TODO: replace legacy strings down below completely with serialized settings json string */
  271. preferencesEditor.putString("name", name);
  272. preferencesEditor.putString("email", email);
  273. preferencesEditor.putString("password", password);
  274. preferencesEditor.apply();
  275. Gson gson = new Gson();
  276. /* read login credentials from SharedPreferences */
  277. SharedPreferences initialCredentialsReader = getSharedPreferences(
  278. "Credentials", Context.MODE_PRIVATE);
  279. String initialReadJsonData = initialCredentialsReader.getString("data", "");
  280. Type credentialsType = new TypeToken<ArrayList<MailServerCredentials>>(){}.getType();
  281. ArrayList<MailServerCredentials> allUsersCredentials = gson.fromJson(initialReadJsonData, credentialsType);
  282. /* check for unique email */
  283. boolean newEmailIsUnique = true;
  284. try {
  285. for (int i = 0; i < allUsersCredentials.size(); i++) {
  286. System.out.println("User #" + i + 1);
  287. System.out.println(allUsersCredentials.get(i).getUsername());
  288. if (allUsersCredentials.get(i).getUsername().equals(email)) {
  289. newEmailIsUnique = false;
  290. break;
  291. }
  292. }
  293. } catch (NullPointerException e) {
  294. System.out.println("creating new arraylist for user credentials, as it seems to be empty");
  295. allUsersCredentials = new ArrayList<>();
  296. }
  297. /* add new email account if the email hasn't been entered before */
  298. if (newEmailIsUnique) {
  299. allUsersCredentials.add(new MailServerCredentials(name, email, password,
  300. MailFunctions.getImapHostFromEmail(email), MailFunctions.getSmtpHostFromEmail(email), 993,
  301. 587, ""));
  302. credentialsEditor.putString("data", gson.toJson(allUsersCredentials, credentialsType));
  303. credentialsEditor.putString("currentUser", email);
  304. credentialsEditor.apply();
  305. showToast("Success: added new email account");
  306. } else {
  307. showToast("Error: cannot add the same email twice");
  308. }
  309. } else {
  310. askForChangeMailServerSettingsDialog(name, email, password);
  311. }
  312. }
  313. });
  314. newemail_cancel_button.setOnClickListener(new View.OnClickListener() {
  315. @Override
  316. public void onClick(View v) {
  317. dialog.dismiss();
  318. }
  319. });
  320. }
  321. /* show debug output in specific view */
  322. private void showSnackbar(View View, String text) {
  323. Snackbar.make(View, text, Snackbar.LENGTH_LONG)
  324. .setAction("Action", null).show();
  325. }
  326. /* like showSnackbar(), but global and uglier */
  327. private void showToast(String text) {
  328. Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
  329. }
  330. @Override
  331. public void selectedMessage(Message messages, EmailViewModel emailViewModel) {
  332. DialogFragment dialog = MessageShowFragment.newInstance(messages, mEmailViewModel);
  333. dialog.show(getSupportFragmentManager(), "tag");
  334. }
  335. }