Kaynağa Gözat

merged readInDBaLayout with master

Simon Hammer 3 yıl önce
ebeveyn
işleme
5374cac04a
36 değiştirilmiş dosya ile 1206 ekleme ve 513 silme
  1. 1 1
      .gitignore
  2. 8 0
      app/build.gradle
  3. 31 17
      app/src/main/java/com/noahvogt/miniprojekt/DataBase/EmailRepository.java
  4. 2 54
      app/src/main/java/com/noahvogt/miniprojekt/DataBase/EmailRoomDatabase.java
  5. 11 1
      app/src/main/java/com/noahvogt/miniprojekt/DataBase/Message.java
  6. 31 14
      app/src/main/java/com/noahvogt/miniprojekt/DataBase/MessageDao.java
  7. 34 0
      app/src/main/java/com/noahvogt/miniprojekt/MailServerCredentials.java
  8. 177 61
      app/src/main/java/com/noahvogt/miniprojekt/MainActivity.java
  9. 4 7
      app/src/main/java/com/noahvogt/miniprojekt/MessageCreateFragment.java
  10. 26 0
      app/src/main/java/com/noahvogt/miniprojekt/data/BooleanTypeAdapter.java
  11. 1 0
      app/src/main/java/com/noahvogt/miniprojekt/data/CustomAdapter.java
  12. 23 0
      app/src/main/java/com/noahvogt/miniprojekt/data/DeleteThread.java
  13. 9 1
      app/src/main/java/com/noahvogt/miniprojekt/data/EmailViewHolder.java
  14. 84 3
      app/src/main/java/com/noahvogt/miniprojekt/data/EmailViewModel.java
  15. 40 44
      app/src/main/java/com/noahvogt/miniprojekt/data/MailFunctions.java
  16. 47 0
      app/src/main/java/com/noahvogt/miniprojekt/data/ReadInMailsActivity.java
  17. 2 1
      app/src/main/java/com/noahvogt/miniprojekt/ui/archive/ArchiveFragment.java
  18. 2 0
      app/src/main/java/com/noahvogt/miniprojekt/ui/gallery/GalleryFragment.java
  19. 2 0
      app/src/main/java/com/noahvogt/miniprojekt/ui/home/HomeFragment.java
  20. 4 3
      app/src/main/java/com/noahvogt/miniprojekt/ui/show/MessageShowFragment.java
  21. 2 0
      app/src/main/java/com/noahvogt/miniprojekt/ui/slideshow/DraftFragment.java
  22. 2 0
      app/src/main/java/com/noahvogt/miniprojekt/ui/spam/SpamFragment.java
  23. 153 0
      app/src/main/java/com/noahvogt/miniprojekt/workers/DownloadWorker.java
  24. 102 136
      app/src/main/python/mailFunctions.py
  25. 10 0
      app/src/main/res/drawable/ic_baseline_call_made_24.xml
  26. 11 0
      app/src/main/res/drawable/ic_baseline_call_received_24.xml
  27. 1 1
      app/src/main/res/layout/fragment_home.xml
  28. 230 0
      app/src/main/res/layout/mail_credentials_customizer.xml
  29. 75 20
      app/src/main/res/layout/message_show_fragment.xml
  30. 0 2
      app/src/main/res/layout/popup.xml
  31. 46 0
      app/src/main/res/layout/welcome.xml
  32. 9 2
      app/src/main/res/menu/main.xml
  33. 1 0
      app/src/main/res/values/dimens.xml
  34. 25 3
      app/src/main/res/values/strings.xml
  35. 0 32
      patches/intent.patch
  36. 0 110
      tests/mailFunctions.py

+ 1 - 1
.gitignore

@@ -1,7 +1,7 @@
 *.iml
 /.idea
 .gradle
-/local.properties
+local.properties
 /.idea/caches
 /.idea/libraries
 /.idea/modules.xml

+ 8 - 0
app/build.gradle

@@ -57,6 +57,11 @@ android {
 
 dependencies {
 
+    implementation 'com.google.code.gson:gson:2.8.7'
+
+    implementation 'androidx.work:work-runtime:2.6.0'
+
+
     implementation 'androidx.appcompat:appcompat:1.2.0'
     implementation 'com.google.android.material:material:1.3.0'
     implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
@@ -82,4 +87,7 @@ dependencies {
     testImplementation 'junit:junit:4.+'
     androidTestImplementation 'androidx.test.ext:junit:1.1.2'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+
+
+
 }

+ 31 - 17
app/src/main/java/com/noahvogt/miniprojekt/DataBase/EmailRepository.java

@@ -9,11 +9,14 @@ import java.util.List;
 public class EmailRepository {
 
     private MessageDao messageDao;
-    private final LiveData<List<Message>> mDraftMessage;
-    private LiveData<List<Message>> mInboxMessage;
-    private LiveData<List<Message>> mSentMessage;
-    private LiveData<List<Message>> mArchiveMessage;
-    private LiveData<List<Message>> mSpamMessage;
+    private final LiveData<List<Message>> mDraftLiveMessage;
+    private LiveData<List<Message>> mInboxLiveMessage;
+    private LiveData<List<Message>> mSentLiveMessage;
+    private LiveData<List<Message>> mArchiveLiveMessage;
+    private LiveData<List<Message>> mSpamLiveMessage;
+
+    private List<Message> mAllMessages;
+
 
 
     // Note that in order to unit test the WordRepository, you have to remove the Application
@@ -24,34 +27,39 @@ public class EmailRepository {
     public EmailRepository(Application application) {
         EmailRoomDatabase db = EmailRoomDatabase.getDatabase(application);
         messageDao = db.messageDao();
-        mInboxMessage = messageDao.getInboxMessages();
-        mDraftMessage = messageDao.getDraftMessages();
-        mArchiveMessage = messageDao.getArchiveMessages();
-        mSentMessage = messageDao.getSentMessages();
-        mSpamMessage = messageDao.getSpamMessages();
+        mInboxLiveMessage = messageDao.getLiveInboxMessages();
+        mDraftLiveMessage = messageDao.getLiveDraftMessages();
+        mArchiveLiveMessage = messageDao.getLiveArchiveMessages();
+        mSentLiveMessage = messageDao.getLiveSentMessages();
+        mSpamLiveMessage = messageDao.getLiveSpamMessages();
     }
 
     // Room executes all queries on a separate thread.
     // Observed LiveData will notify the observer when the data has changed.
     /* returns all messages of with tag Draft */
     public LiveData<List<Message>> getDraftMessages() {
-        return mDraftMessage;
+        return mDraftLiveMessage;
     }
 
-    public LiveData<List<Message>> getSpamMessage(){return mSpamMessage;}
+    public LiveData<List<Message>> getSpamMessage(){return mSpamLiveMessage;}
 
     public LiveData<List<Message>> getInboxMessages() {
-        return mInboxMessage;
+        return mInboxLiveMessage;
     }
 
     public LiveData<List<Message>> getSentMessages() {
-        return mSentMessage;
+        return mSentLiveMessage;
     }
 
     public LiveData<List<Message>> getArchiveMessages() {
-        return mArchiveMessage;
+        return mArchiveLiveMessage;
     }
 
+    /* problems with main Thread
+    public List<Message> getAllMessages(){ return mAllMessages;}
+
+     */
+
     // You must call this on a non-UI thread or your app will throw an exception. Room ensures
     // that you're not doing any long running operations on the main thread, blocking the UI.
     public void insert(Message message) {
@@ -66,9 +74,15 @@ public class EmailRepository {
         });
     }
 
-    public void updateMessage(final int id, String folder){
+    public void updateFolder(final int id, String folder){
+        EmailRoomDatabase.databaseWriteExecutor.execute(() -> {
+            messageDao.updateFolder(id ,folder);
+        });
+    }
+
+    public void updateDate(final int id, final String date){
         EmailRoomDatabase.databaseWriteExecutor.execute(() -> {
-            messageDao.updateMessage(id ,folder);
+            messageDao.updateDate(id, date);
         });
     }
 }

+ 2 - 54
app/src/main/java/com/noahvogt/miniprojekt/DataBase/EmailRoomDatabase.java

@@ -32,8 +32,8 @@ public abstract class EmailRoomDatabase extends RoomDatabase{
         }
     };
 
-    /* creating 4 threads */
-    private static final int NUMBER_OF_THREADS = 4;
+    /* creating n threads */
+    private static final int NUMBER_OF_THREADS = 6;
     static final ExecutorService databaseWriteExecutor =
             Executors.newFixedThreadPool(NUMBER_OF_THREADS);
 
@@ -65,58 +65,6 @@ public abstract class EmailRoomDatabase extends RoomDatabase{
                 // Populate the database in the background.
                 // If you want to start with more words, just add them.
                 MessageDao dao = INSTANCE.messageDao();
-                dao.deleteAll();
-
-
-                Message word = new Message("Noah", null , null,
-                        "Samuel", "31.09.21", "inboxTest", "I Try my best", "Inbox",
-                        true);
-                dao.insert(word);
-
-                word = new Message("Pueblo", "my Man, your Girl", null,
-                        "Escobar", "31.02.21", "DateSortTest", "I hope the Sorting works", "Inbox",
-                        true);
-                dao.insert(word);
-
-                word = new Message("Pueblo", "my Man, your Girl", null,
-                        "Escobar", "31.02.21", "VariableTest", "I hope the Sorting works", "Inbox",
-                        true);
-                dao.insert(word);
-
-                word = new Message("Again", null, null, "Again", "31.09.21", "DateTest",
-                        "Does this Date work know?", "Inbox", true);
-                dao.insert(word);
-
-
-                word = new Message("Noah", null, null,
-                       "arldemeier", "bobo", "sentTest", "i could cry", "Sent",
-                       true);
-                dao.insert(word);
-
-
-
-               /*
-               for (int i = 1; i < 20; i++){
-                   word = new Message("Simon", null, null,
-                           "Hans", "tomorrow", "inbox20", "lets goo","Inbox",
-                           true);
-                   dao.insert(word);
-               }
-
-
-                word = new Message("Simon", null, null,
-                        "Maurice", "yesterday", "ArchiveTest", "lets goo","Archive",
-                        true);
-                dao.insert(word);
-
-                word = new Message("Simon", null, null,
-                        "Lenny", "tomorrow", "SpamTest", "lets goo","Spam",
-                        true);
-                dao.insert(word);
-
-
-                */
-
 
             });
         }

+ 11 - 1
app/src/main/java/com/noahvogt/miniprojekt/DataBase/Message.java

@@ -5,6 +5,8 @@ import androidx.room.ColumnInfo;
 import androidx.room.Entity;
 import androidx.room.PrimaryKey;
 
+import com.google.gson.annotations.SerializedName;
+
 /* @Embedded to express entitys together
  *  https://developer.android.com/training/data-storage/room/relationships
  * to learn more */
@@ -18,34 +20,42 @@ public class Message {
     /* name of Columm */
     @NonNull
     @ColumnInfo(name = "to")
+    @SerializedName("to")
     private String mTo ;
 
-
     @ColumnInfo(name = "cc")
+    @SerializedName("cc")
     private String mCc;
 
     @ColumnInfo(name = "bcc")
+    @SerializedName("bcc")
     private String mBcc; //blind carpet copy, not see who sees mails
 
     @NonNull
     @ColumnInfo(name = "fromEmail")
+    @SerializedName("from")
     private String mFrom;
 
     @NonNull
     @ColumnInfo(name = "date")
+    @SerializedName("date")
     private String mDate;
 
     @ColumnInfo(name = "subject")
+    @SerializedName("subject")
     private String mSubject;
 
     @ColumnInfo(name = "textContent")
+    @SerializedName("content")
     private String mTextContent;
 
     @NonNull
     @ColumnInfo(name = "folder")
+    @SerializedName("folder")
     private String mFolder;
 
     @ColumnInfo(name = "seen")
+    @SerializedName("seen")
     private boolean mSeen;
 
     public String getTo(){return this.mTo;}

+ 31 - 14
app/src/main/java/com/noahvogt/miniprojekt/DataBase/MessageDao.java

@@ -19,46 +19,63 @@ public interface MessageDao {
     @Insert(onConflict = OnConflictStrategy.IGNORE)
     void insert(Message message);
 
-    @Query("DELETE FROM message_table")
-    void deleteAll();
+    @Query("DELETE FROM message_table WHERE folder = :folder")
+    void deleteFolder(String folder);
 
     @Delete(entity = Message.class)
     void delete(Message message);
 
+    @Delete(entity = Message.class)
+    void deleteAll(String folder);
+
     @Query("UPDATE message_table SET folder = :folder WHERE id = :id")
-    void updateMessage(int id, String folder);
+    void updateFolder(int id, String folder);
 
-    @Query("DELETE FROM message_table WHERE subject='DELETE'")
-    void deleteNewMessage();
+    @Query("UPDATE message_table SET date = :date WHERE id = :id")
+    void updateDate(int id, String date);
 
 
-    @Query("SELECT * FROM message_table")
-    LiveData<List<Message>> getAllMessages();
+    @Query("SELECT * FROM message_table ORDER BY id ASC")
+    List<Message> getAllMessages();
 
-    /*gets messages all messages ordered by date
-    * !IMPORTANT I don't know in which direction */
+    /*gets messages all messages ordered by date */
     @Query("SELECT * FROM message_table ORDER BY date ASC")
     LiveData<List<Message>> getDateMessages();
 
     /* get Draft messages*/
     @Query("SELECT * FROM message_table WHERE folder LIKE 'Draft' ORDER BY date DESC")
-    LiveData<List<Message>> getDraftMessages();
+    LiveData<List<Message>> getLiveDraftMessages();
+
+    @Query("SELECT * FROM message_table WHERE folder LIKE 'Draft' ORDER BY date DESC")
+    List<Message> getDraftMessages();
 
     /* get Inbox messages*/
     @Query("SELECT * FROM message_table WHERE folder LIKE 'Inbox' ORDER BY date DESC")
-    LiveData<List<Message>> getInboxMessages();
+    LiveData<List<Message>> getLiveInboxMessages();
+
+    @Query("SELECT * FROM message_table WHERE folder LIKE 'Inbox' ORDER BY date DESC")
+    List<Message> getInboxMessages();
 
     /* get Sent messages*/
     @Query("SELECT * FROM message_table WHERE folder LIKE 'Sent' ORDER BY date DESC")
-    LiveData<List<Message>> getSentMessages();
+    LiveData<List<Message>> getLiveSentMessages();
+
+    @Query("SELECT * FROM message_table WHERE folder LIKE 'Sent' ORDER BY date DESC")
+    List<Message> getSentMessages();
 
     /* get Archive messages*/
     @Query("SELECT * FROM message_table WHERE folder LIKE 'Archive' ORDER BY date DESC")
-    LiveData<List<Message>> getArchiveMessages();
+    LiveData<List<Message>> getLiveArchiveMessages();
+
+    @Query("SELECT * FROM message_table WHERE folder LIKE 'Archive' ORDER BY date DESC")
+    List<Message> getArchiveMessages();
 
     /* get Spam messages*/
     @Query("SELECT * FROM message_table WHERE folder LIKE 'Spam' ORDER BY date DESC")
-    LiveData<List<Message>> getSpamMessages();
+    LiveData<List<Message>> getLiveSpamMessages();
+
+    @Query("SELECT * FROM message_table WHERE folder LIKE 'Spam' ORDER BY date DESC")
+    List<Message> getSpamMessages();
 
 
 }

+ 34 - 0
app/src/main/java/com/noahvogt/miniprojekt/MailServerCredentials.java

@@ -0,0 +1,34 @@
+package com.noahvogt.miniprojekt;
+
+public class MailServerCredentials {
+    private String mImapHost;
+    private String mSmtpHost;
+    private String mUsername;
+    private String mPassword;
+    private int mImapPort;
+    private int mSmtpPort;
+    private String mName;
+    private String mSignature;
+
+    public String getImapHost () {return this.mImapHost;}
+    public String getSmtpHost () {return this.mSmtpHost;}
+    public String getUsername () {return this.mUsername;}
+    public String getPassword () {return this.mPassword;}
+    public int getImapPort () {return this.mImapPort;}
+    public int getSmtpPort () {return  this.mSmtpPort;}
+    public String getName () {return this.mName;}
+    public String getSignature () {return this.mSignature;}
+
+    public MailServerCredentials(String name, String username, String password, String imapHost, String smtpHost, int imapPort, int smtpPort, String signature) {
+        mName = name;
+        mUsername = username;
+        mPassword = password;
+
+        mImapHost = imapHost;
+        mImapPort = imapPort;
+        mSmtpPort = smtpPort;
+        mSmtpHost = smtpHost;
+
+        mSignature = signature;
+    }
+}

+ 177 - 61
app/src/main/java/com/noahvogt/miniprojekt/MainActivity.java

@@ -1,13 +1,18 @@
 package com.noahvogt.miniprojekt;
 
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.Menu;
+import android.view.MenuItem;
 import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
+import android.widget.PopupMenu;
+import android.widget.TextView;
 import android.widget.Toast;
 
 import androidx.appcompat.app.AlertDialog;
@@ -18,6 +23,8 @@ import androidx.fragment.app.DialogFragment;
 
 
 import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
 import com.noahvogt.miniprojekt.DataBase.Message;
 
 import androidx.fragment.app.Fragment;
@@ -33,19 +40,30 @@ import androidx.navigation.NavController;
 import androidx.navigation.Navigation;
 import androidx.navigation.ui.AppBarConfiguration;
 import androidx.navigation.ui.NavigationUI;
+import androidx.work.Data;
 
 import com.chaquo.python.Python;
 import com.chaquo.python.android.AndroidPlatform;
 import com.google.android.material.snackbar.Snackbar;
 import com.noahvogt.miniprojekt.data.CustomAdapter;
+import com.noahvogt.miniprojekt.data.DeleteThread;
 import com.noahvogt.miniprojekt.data.EmailViewModel;
 import com.noahvogt.miniprojekt.data.MailFunctions;
+import com.noahvogt.miniprojekt.workers.DownloadWorker;
 import com.noahvogt.miniprojekt.ui.show.MessageShowFragment;
+import com.noahvogt.miniprojekt.data.BooleanTypeAdapter;
 
+import java.lang.reflect.Type;
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
+import com.google.gson.Gson;
+
+
+
 import static com.noahvogt.miniprojekt.R.id.drawer_layout;
 
 public class MainActivity extends AppCompatActivity implements View.OnClickListener, CustomAdapter.SelectedMessage {
@@ -53,15 +71,19 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
     private AppBarConfiguration mAppBarConfiguration;
 
     public static final int NEW_WORD_ACTIVITY_REQUEST_CODE = 1;
+    public static final String emailData = "Email";
+    public static final String passwordData = "Password";
+    public static final String nameData = "Name";
     public static EmailViewModel mEmailViewModel;
     public static RecyclerView recyclerView;
+    private Boolean clicked = false;
 
     private AlertDialog dialog;
     private EditText newemail_name, newemail_email, newemail_password; /* may not be private */
 
-    SharedPreferences preferences;
+    SharedPreferences preferences, mailServerCredentials;
 
-    /* empty descriptor */
+    /* leave descriptor empty */
     public MainActivity() {}
 
 
@@ -89,11 +111,20 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
 
         /* define button listeners */
 
+        final Boolean[] clicked = {false};
         Button add_email_button = (Button) findViewById(R.id.addEmailButton);
         add_email_button.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                createNewEmailDialog();
+                if (!clicked[0]){
+
+                    createInformation(true);
+                    clicked[0] = true;
+
+
+                } else {
+                    createNewEmailDialog();
+                }
             }
         });
 
@@ -109,6 +140,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
         /* invoke preferences */
         preferences = getSharedPreferences("UserPreferences", Context.MODE_PRIVATE);
 
+        mailServerCredentials = getSharedPreferences("Credentials", Context.MODE_PRIVATE);
+
         /* invoke toolbar */
         Toolbar toolbar = findViewById(R.id.toolbar);
         setSupportActionBar(toolbar);
@@ -157,7 +190,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
         });
 
 
-
         /* Start email Writer*/
         FloatingActionButton message_create_button = findViewById(R.id.messageButton);
         message_create_button.setOnClickListener(new View.OnClickListener() {
@@ -169,6 +201,11 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
 
             }
         });
+
+        /* start python instance right on startup */
+        if (! Python.isStarted()) {
+            Python.start(new AndroidPlatform(this));
+        }
     }
 
 
@@ -185,17 +222,14 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
          //   if (requestCode == NEW_WORD_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
                 Message word = new Message(
                         MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.EXTRA_TO),
-                        null,
-                        null,
+                        MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.EXTRA_CC),
+                        MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.EXTRA_BCC),
                         MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.EXTRA_FROM),
                         ft.format(dNow),
                         MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.EXTRA_SUBJECT),
                         MessageCreateFragment.replyIntent.getStringExtra(MessageCreateFragment.EXTRA_MESSAGE),
                         "Draft",false);
                 mEmailViewModel.insert(word);
-
-
-
         }
 
 
@@ -204,6 +238,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
     public boolean onCreateOptionsMenu(Menu menu) {
         /* Inflate the menu; this adds items to the action bar if it is present. */
         getMenuInflater().inflate(R.menu.main, menu);
+
         return true;
     }
 
@@ -218,7 +253,88 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
     /* better leave empty to avoid any listener disambiguity */
     public void onClick(View view) { }
 
+    public void changeMailServerSettingsDialog(String name, String email, String password) {
+        /* define View window */
+        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
+        final View changeMailServerSettingsView = getLayoutInflater().inflate(R.layout.mail_credentials_customizer, null);
+
+        EditText incomingServerObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_incoming_server_text);
+        EditText outgoingServerObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_outgoing_server_text);
+        EditText incomingPortObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_incoming_port_text);
+        EditText outgoingPortObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_outgoing_port_text);
+        EditText serverUsernameObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_username_text);
+        EditText passwordObject = (EditText) changeMailServerSettingsView.findViewById(R.id.custom_mail_server_password_text);
+
+        /* set assumed input in corresponding fields */
+        incomingServerObject.setText(MailFunctions.getImapHostFromEmail(email));
+        outgoingServerObject.setText(MailFunctions.getSmtpHostFromEmail(email));
+        incomingPortObject.setText("993");
+        outgoingPortObject.setText("587");
+        serverUsernameObject.setText(email);
+        passwordObject.setText(password);
+
+        /* TODO: add save and cancel button functionality */
+
+        /* open View window */
+        dialogBuilder.setView(changeMailServerSettingsView);
+        dialog = dialogBuilder.create();
+        dialog.show();
+    }
+
+    public void askForChangeMailServerSettingsDialog(String name, String email, String password) {
+        /* define View window */
+        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
+
+        /* open View window */
+        dialogBuilder.setTitle("failed to connect :(");
+        dialogBuilder
+                .setMessage("Do you want to further customize your mail server settings?")
+                .setPositiveButton("Yes",new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int id) {
+                        /*if this button is clicked, close the whole fragment */
+                        changeMailServerSettingsDialog(name, email, password);
+                    }
+                })
+                .setNegativeButton("No",new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog,int id) {
+                        /* if this button is clicked, close the hole fragment */
+                        dialog.dismiss();
+                    }
+                });
+        dialog = dialogBuilder.create();
+        dialog.show();
+    }
+
+    public void createInformation(boolean button){
+        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MainActivity.this);
+        final View emailPopupView = getLayoutInflater().inflate(R.layout.welcome, null);
+
+        /* init text field variables */
+        TextView shedText = emailPopupView.findViewById(R.id.backgroun);
+        Button okayButton = emailPopupView.findViewById(R.id.okay_button);
+
+        /* open View window */
+        dialogBuilder.setView(emailPopupView);
+        dialog = dialogBuilder.create();
+        dialog.show();
+
+        okayButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                dialog.dismiss();
+                if (button){
+                    createNewEmailDialog();
+                }
+            }
+        });
+    }
 
+    public static MailServerCredentials newMailServerCredentials;
+    public static SharedPreferences.Editor credentialsEditor;
+    String name;
+    String email;
+    String password;
+    Data.Builder builder = new Data.Builder();
 
     public void createNewEmailDialog(){
         /* define View window */
@@ -242,6 +358,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
         dialog.show();
 
         SharedPreferences.Editor preferencesEditor = preferences.edit();
+        credentialsEditor = mailServerCredentials.edit();
 
         if (! Python.isStarted()) {
             Python.start(new AndroidPlatform(this));
@@ -253,74 +370,41 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
             public void onClick(View v) {
 
                 /* store user input (only needed for DEBUGGING) */
-                String name = newemail_name.getText().toString();
-                String email = newemail_email.getText().toString();
-                String password = newemail_password.getText().toString();
+                name = newemail_name.getText().toString();
+                email = newemail_email.getText().toString();
+                password = newemail_password.getText().toString();
+
+                builder = new Data.Builder();
+                builder.putString(emailData, email)
+                        .putString(passwordData, password)
+                        .putString(nameData, name);
 
                 if (!MailFunctions.validateEmail(newemail_email) | !MailFunctions.validateName(newemail_name) | !MailFunctions.validatePassword(newemail_password)) {
                     return;
                 }
-
                 /* connect to mail server and print various debugging output */
                 showToast("Probe Connection ...");
-                if (MailFunctions.canConnect(name, email, password) == Boolean.TRUE) {
+                if (MailFunctions.canConnect(MailFunctions.getImapHostFromEmail(email), email, password) == Boolean.TRUE) {
                     showToast("was able to connect");
-                    List folders =  MailFunctions.listMailboxes(MailFunctions.getIMAPConnection(name, email, password));
-                    for (int i = 0; i < folders.size(); i++) {
-                        showToast(folders.get(i).toString());
-                        // TODO: select right folder to store, Synchronization
-                        /*gives list of Message Objects/dictionaries */
-                        List messages = MailFunctions.fetchMailsFromBox(MailFunctions.getIMAPConnection(name, email, password), folders.get(i).toString(), "list");
-                        System.out.println(folders.get(i).toString());
-                        System.out.println(messages.toString());
-
-
-                        for (int k = 0; k < messages.size(); k++) {
-                            System.out.println(messages.get(k));
-                                /*work now, but list of Messages not */
-
-
-
-
-                        }
-
-                    }
 
-                    /*Message word = new Message(
-                            messageCreateFragment.replyIntent.getStringExtra(messageCreateFragment.EXTRA_TO),
-                            null,
-                            null,
-                            messageCreateFragment.replyIntent.getStringExtra(messageCreateFragment.EXTRA_FROM),
-                            ft.format(dNow),
-                            messageCreateFragment.replyIntent.getStringExtra(messageCreateFragment.EXTRA_SUBJECT),
-                            messageCreateFragment.replyIntent.getStringExtra(messageCreateFragment.EXTRA_MESSAGE),
-                            "Draft",false);
-                    mEmailViewModel.insert(word);
-
-                     */
+                    /* TODO: replace legacy strings down below completely with serialized settings json string */
                     preferencesEditor.putString("name", name);
                     preferencesEditor.putString("email", email);
                     preferencesEditor.putString("password", password);
                     preferencesEditor.apply();
-                } else {
-                    showToast("failed to connect");
-
-                    /* show all strings the user gave, this will later be stored to a secure database and checked for validation */
-                    showToast(name);
-                    showToast(email);
-                    showToast(password);
-                }
 
+                    dialog.dismiss();
+                    /*makes request to worker and gives data to it*/
+                    mEmailViewModel.applyDownload(builder.build());
 
+                } else {
+                    askForChangeMailServerSettingsDialog(name, email, password);
+                }
             }
         });
 
-        newemail_cancel_button.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                dialog.dismiss();
-            }
-        });
+
+        newemail_cancel_button.setOnClickListener(v -> dialog.dismiss());
 
     }
 
@@ -339,10 +423,42 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
 
     @Override
     public void selectedMessage(Message messages, EmailViewModel emailViewModel) {
-
         DialogFragment dialog = MessageShowFragment.newInstance(messages, mEmailViewModel);
         dialog.show(getSupportFragmentManager(), "tag");
 
     }
+
+    private static final String TAG = DownloadWorker.class.getSimpleName();
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()){
+            case R.id.action_information:
+                try {
+                    SimpleDateFormat rawDate = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
+                    SimpleDateFormat date = new SimpleDateFormat("dd.MM.yy");
+                    Date middleDate = rawDate.parse("Thu, 12 Aug 2021 19:21:13 +0000 (UTC)");
+                    String newDate = date.format(middleDate);
+                } catch (Throwable throwable) {
+                    Log.e(TAG, "Error formating date", throwable );
+                }
+
+                createInformation(false);
+                return true;
+            case R.id.action_refresh:
+                mEmailViewModel.applyDownload(builder.build());
+                return true;
+            case R.id.action_deletefolder:
+                showToast("clicked delete all");
+                mEmailViewModel.getAll(false);
+                for (int delete = 0; delete < mEmailViewModel.getAll(false).size(); delete++){
+                    mEmailViewModel.deleteMessage(mEmailViewModel.getAll(false).get(delete));
+                }
+                mEmailViewModel.getAll(true);
+
+                return true;
+        }
+        return false;
+    }
 }
 

+ 4 - 7
app/src/main/java/com/noahvogt/miniprojekt/MessageCreateFragment.java

@@ -117,7 +117,7 @@ public class MessageCreateFragment extends DialogFragment implements PopupMenu.O
 
         /* TODO: add cc + bcc functionality */
 
-        /* dosen't wotk cause Activity is not extendet and used as variable */
+        /* doesn't work cause Activity is not extended and used as variable */
 
 
 
@@ -138,7 +138,7 @@ public class MessageCreateFragment extends DialogFragment implements PopupMenu.O
                     dismiss();
                 }
                 else {
-                    /* setup dialog */
+                    /* setup dialog for saving draft message */
                     AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
                     alertDialogBuilder.setTitle("Warning");
                     alertDialogBuilder
@@ -171,7 +171,7 @@ public class MessageCreateFragment extends DialogFragment implements PopupMenu.O
                                     Intent intent = new Intent(getContext(), NewDraftMessageActivity.class);
                                     startActivityForResult(intent, MainActivity.NEW_WORD_ACTIVITY_REQUEST_CODE);
 
-                                    /*if this button is clicked, close the whole fragment */
+                                    /* close the whole fragment */
                                     dismiss();
                                 }
                             })
@@ -219,8 +219,7 @@ public class MessageCreateFragment extends DialogFragment implements PopupMenu.O
 
                 /* check for valid input */
                 if (MailFunctions.validateMessageBody(messageBodyObject) && MailFunctions.validateSubject(subjectObject) &&
-                MailFunctions.validateEmail(receivingAddressObject) && MailFunctions.validateEmail(sendingAddressObject) &&
-                !MailFunctions.checkForSameEmail(sendingAddressObject, receivingAddressObject)) {
+                MailFunctions.validateEmail(receivingAddressObject) && MailFunctions.validateEmail(sendingAddressObject)) {
                     String password = preferences.getString("password","");
                     MailFunctions.sendStarttlsMail("smtp.edubs.ch", sendingAddress, receivingAddress, password, messageBody, subject, ccStr, bccStr);
                     Toast.makeText(getActivity(), "sending ... ", Toast.LENGTH_SHORT).show();
@@ -228,8 +227,6 @@ public class MessageCreateFragment extends DialogFragment implements PopupMenu.O
                 } else {
                     Toast.makeText(getActivity(), "Please check your input", Toast.LENGTH_SHORT).show();
                 }
-
-                /* TODO: implement actual sending functionality */
             }
         });
 

+ 26 - 0
app/src/main/java/com/noahvogt/miniprojekt/data/BooleanTypeAdapter.java

@@ -0,0 +1,26 @@
+package com.noahvogt.miniprojekt.data;
+
+import java.lang.reflect.Type;
+import com.google.gson.*;
+public class BooleanTypeAdapter implements JsonDeserializer<Boolean> {
+    public Boolean deserialize(JsonElement json, Type typeOfT,
+                               JsonDeserializationContext context) throws JsonParseException {
+        if (((JsonPrimitive) json).isBoolean()) {
+            return json.getAsBoolean();
+        }
+        if (((JsonPrimitive) json).isString()) {
+            String jsonValue = json.getAsString();
+            if (jsonValue.equalsIgnoreCase("true")) {
+                return true;
+            } else if (jsonValue.equalsIgnoreCase("false")) {
+                return false;
+            } else {
+                return null;
+            }
+        }
+
+        int code = json.getAsInt();
+        return code == 0 ? false :
+                code == 1 ? true : null;
+    }
+}

+ 1 - 0
app/src/main/java/com/noahvogt/miniprojekt/data/CustomAdapter.java

@@ -39,6 +39,7 @@ public class CustomAdapter extends ListAdapter<Message, EmailViewHolder> {
 
     /*get List from adapter which is shown*/
     public void getList(List<Message> messageList){
+        System.out.println("GetList Adapter Loop");
         this.messageList = messageList;
     }
 

+ 23 - 0
app/src/main/java/com/noahvogt/miniprojekt/data/DeleteThread.java

@@ -0,0 +1,23 @@
+package com.noahvogt.miniprojekt.data;
+
+import android.os.AsyncTask;
+
+import static com.noahvogt.miniprojekt.MainActivity.mEmailViewModel;
+
+public class DeleteThread extends AsyncTask<Boolean, Void, Void> implements Runnable {
+
+    @Override
+    public void run() {
+       /* for (int delete = 0; delete <= mEmailViewModel.getAllMessages().size(); delete++){
+            mEmailViewModel.deleteMessage(mEmailViewModel.getAllMessages().get(delete));
+        }
+
+        */
+    }
+
+    @Override
+    protected Void doInBackground(Boolean... booleans) {
+
+        return null;
+    }
+}

+ 9 - 1
app/src/main/java/com/noahvogt/miniprojekt/data/EmailViewHolder.java

@@ -1,6 +1,8 @@
 package com.noahvogt.miniprojekt.data;
 
 import android.annotation.SuppressLint;
+import android.content.Context;
+import android.os.Build;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -8,8 +10,10 @@ import android.widget.TextView;
 import android.widget.Toast;
 
 import com.noahvogt.miniprojekt.DataBase.Message;
+import com.noahvogt.miniprojekt.MainActivity;
 import com.noahvogt.miniprojekt.R;
 
+import androidx.annotation.RequiresApi;
 import androidx.recyclerview.widget.RecyclerView;
 
 import java.text.ParseException;
@@ -33,6 +37,8 @@ public class EmailViewHolder extends RecyclerView.ViewHolder {
         subjectItemView = itemView.findViewById(R.id.subject);
         dateItemView = itemView.findViewById(R.id.date);
         messageItemView = itemView.findViewById(R.id.message);
+        System.out.println("Called EmailViewHolder");
+        
         itemView.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -55,13 +61,15 @@ public class EmailViewHolder extends RecyclerView.ViewHolder {
         if (message.length() > 30){
             message = message.substring(0,30) + "...";
         }
-        if (date.length() > 9){
+        /*if (date.length() > 9){
             date = "INVALID";
         }
         if (!isDate(date)){
             date = "INVALID";
         }
 
+         */
+
         fromItemView.setText(from);
         subjectItemView.setText(subject);
         dateItemView.setText(date);

+ 84 - 3
app/src/main/java/com/noahvogt/miniprojekt/data/EmailViewModel.java

@@ -4,24 +4,38 @@ import android.app.Application;
 
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.AndroidViewModel;
+import androidx.work.Data;
+import androidx.work.OneTimeWorkRequest;
+import androidx.work.WorkManager;
 
 import com.noahvogt.miniprojekt.DataBase.EmailRepository;
 import com.noahvogt.miniprojekt.DataBase.Message;
+import com.noahvogt.miniprojekt.workers.DownloadWorker;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public class EmailViewModel extends AndroidViewModel {
 
     private EmailRepository mEmailRepository;
+    private WorkManager mWorkManager;
 
+    public List<Message> all =  new ArrayList<>();
     private LiveData<List<Message>> mDraftMessage;
     private LiveData<List<Message>> mInboxMessage;
     private LiveData<List<Message>> mSentMessage;
     private LiveData<List<Message>> mArchiveMessage;
     private LiveData<List<Message>> mSpamMessage;
 
+    String sent;
+    String spam;
+    String archive;
+    String inbox;
+    String drafts;
+
     public EmailViewModel(Application application) {
         super(application);
+        mWorkManager = WorkManager.getInstance(application);
         mEmailRepository = new EmailRepository(application);
         mInboxMessage = mEmailRepository.getInboxMessages();
         mDraftMessage = mEmailRepository.getDraftMessages();
@@ -30,10 +44,71 @@ public class EmailViewModel extends AndroidViewModel {
         mSpamMessage = mEmailRepository.getSpamMessage();
     }
 
-    public LiveData<List<Message>> getDraftMessage(){
-        return mDraftMessage;
+    /*requests Worker and applies password, email to it */
+    public void applyDownload(Data data){
+        OneTimeWorkRequest downloadRequest =
+                new OneTimeWorkRequest.Builder(DownloadWorker.class)
+                        .setInputData(data)
+                        .build();
+
+        mWorkManager.enqueue(downloadRequest);
+    }
+
+    public void setListAll(List<Message> messageListAll, String fragment){
+        System.out.println("setListAll: size messageListAll: " + messageListAll.size());
+        if (sent == null && fragment.equals("Sent")){
+            for (int i = 0; i < messageListAll.size(); i++) {
+                this.all.add(messageListAll.get(i));
+            }
+            sent = fragment;
+        }
+
+        if (drafts == null && fragment.equals("Drafts")){
+            for (int i = 0; i < messageListAll.size(); i++) {
+                this.all.add(messageListAll.get(i));
+            }
+            drafts = fragment;
+        }
+
+        if (archive == null && fragment.equals("Archive")){
+            for (int i = 0; i < messageListAll.size(); i++) {
+                this.all.add(messageListAll.get(i));
+            }
+            archive = fragment;
+        }
+        if (inbox == null && fragment.equals("Inbox")){
+            for (int i = 0; i < messageListAll.size(); i++) {
+                this.all.add(messageListAll.get(i));
+            }
+            inbox = fragment;
+        }
+        if (spam == null && fragment.equals("Spam")){
+            for (int i = 0; i < messageListAll.size(); i++) {
+                this.all.add(messageListAll.get(i));
+            }
+            spam = fragment;
+        }
+        System.out.println("SetListAll: List of All: " + all);
+        System.out.println("setListAll: size all: " + all.size());
+    }
+
+    public List<Message> getAll(boolean status){
+        System.out.println("getAll: Size of all Lists " + all.size());
+        for (int i = 0; i < all.size(); i++) {
+            System.out.println("EmailModel all list " + all.get(i) + "\n Size: " + all.size());
+        }
+        if (status){
+            List<Message> emptyAll;
+            emptyAll = all;
+            all.clear();
+            System.out.println("Size cleared list:" + all.size());
+            return emptyAll;
+        }
+        return all;
     }
 
+    public LiveData<List<Message>> getDraftMessage(){ return mDraftMessage; }
+
     public LiveData<List<Message>> getSpamMessage(){return mSpamMessage;}
 
     public LiveData<List<Message>> getInboxMessage(){ return mInboxMessage;}
@@ -42,9 +117,15 @@ public class EmailViewModel extends AndroidViewModel {
 
     public LiveData<List<Message>> getArchiveMessage(){ return mArchiveMessage;}
 
+    //public List<Message> getAllMessages(){return mAllMessages;}
+
     public void insert(Message message){mEmailRepository.insert(message);}
 
     public void deleteMessage(Message message){mEmailRepository.deleteMessage(message);}
 
-    public void updateMessage(int id, String folder){mEmailRepository.updateMessage(id, folder);}
+    public void updateFolder(int id, String folder){mEmailRepository.updateFolder(id, folder);}
+
+    public void updateDate(int id, String date){ mEmailRepository.updateDate(id, date); }
+
+
 }

+ 40 - 44
app/src/main/java/com/noahvogt/miniprojekt/data/MailFunctions.java

@@ -22,10 +22,10 @@ public class MailFunctions {
         pythonMailFunctions.callAttr("sendStarttls", host, sendingMail, receivingMail, password, message, subject, 587, cc, bcc);
     }
 
-    public static PyObject getIMAPConnection(String host, String email, String password) {
+    public static PyObject getIMAPConnection(String host, String email, String password, int port) {
         Python python = Python.getInstance();
         PyObject pythonMailFunctions = python.getModule("mailFunctions");
-        return pythonMailFunctions.callAttr("connect", host, email, password, 993);
+        return pythonMailFunctions.callAttr("connect", host, email, password, port);
     }
 
     public static List listMailboxes(PyObject IMAPConnection) {
@@ -33,51 +33,11 @@ public class MailFunctions {
         PyObject pythonMailFunctions = python.getModule("mailFunctions");
         return pythonMailFunctions.callAttr("listMailboxes", IMAPConnection).asList();
     }
-
-    public static List fetchMailsFromBox(PyObject IMAPConnection, String Folder, String InputType) {
+    public static String fetchMailsFromBox(PyObject IMAPConnection, String FolderServer, String FolderLocal) {
         Python python = Python.getInstance();
         PyObject pythonMailFunctions = python.getModule("mailFunctions");
-        return pythonMailFunctions.callAttr("fetchMails", IMAPConnection, Folder, InputType).asList();
-    }
-/*
-    public static String fetchSubject(int messageIndex){
-        Python python = Python.getInstance();
-        PyObject pythonMailFunction = python.getModule("mailFunctions");
-        return pythonMailFunction.callAttr("printSubject", messageIndex).toString();
-    }
-
-    public static String fetchFrom(int messageIndex){
-        Python python = Python.getInstance();
-        PyObject pythonMailFunction = python.getModule("mailFunctions");
-        return pythonMailFunction.callAttr("printFrom", messageIndex).toString();
-    }
-    public static String fetchTo(int messageIndex){
-        Python python = Python.getInstance();
-        PyObject pythonMailFunction = python.getModule("mailFunctions");
-        return pythonMailFunction.callAttr("printTo", messageIndex).toString();
+        return pythonMailFunctions.callAttr("fetchMails", IMAPConnection, FolderServer, FolderLocal).toString();
     }
-    public static String fetchBcc(int messageIndex){
-        Python python = Python.getInstance();
-        PyObject pythonMailFunction = python.getModule("mailFunctions");
-        return pythonMailFunction.callAttr("printBcc", messageIndex).toString();
-    }
-    public static String fetchCC(int messageIndex){
-        Python python = Python.getInstance();
-        PyObject pythonMailFunction = python.getModule("mailFunctions");
-        return pythonMailFunction.callAttr("printCc", messageIndex).toString();
-    }
-    public static String fetchDate(int meassageIndex){
-        Python python = Python.getInstance();
-        PyObject pythonMailFunction = python.getModule("mailFunctions");
-        return pythonMailFunction.callAttr("printDate", meassageIndex).toString();
-    }
-    public static String fetchContent(int messageIndex){
-        Python python = Python.getInstance();
-        PyObject pythonMailFunction = python.getModule("mailFunctions");
-        return pythonMailFunction.callAttr("printContent", messageIndex).toString();
-
- */
-
     public static boolean validateName(EditText emailName) {
         String name = emailName.getText().toString().trim();
 
@@ -93,6 +53,42 @@ public class MailFunctions {
         }
     }
 
+    public static String getImapHostFromEmail(String email) {
+        String topLevelHost = email.substring(email.lastIndexOf("@") + 1);
+        if (topLevelHost.endsWith("edubs.ch")) {
+            return "teamwork.edubs.ch";
+
+        }else if (topLevelHost.endsWith("yahoo.com")){
+            return "imap.mail.yahoo.com";
+
+        } else if (topLevelHost.endsWith("gmx.ch")){
+            return "imap.gmx.net";
+        } else if (topLevelHost.endsWith("gmx.de")){
+            return "imap.gmx.net";
+        }
+        else {
+            return "imap." + topLevelHost;
+        }
+    }
+
+    public static String getSmtpHostFromEmail(String email) {
+        String topLevelHost = email.substring(email.lastIndexOf("@") + 1);
+        if (topLevelHost.equals("noahvogt.com")) {
+            return "mail.noahvogt.com";
+
+        } else if (topLevelHost.endsWith("yahoo.com")){
+            return "smtp.mail.yahoo.com";
+        }else if (topLevelHost.endsWith("gmx.ch")){
+            return  "mail.gmx.net";
+        }else if (topLevelHost.endsWith("gmx.de")) {
+            return "mail.gmx.net";
+        }
+        else {
+            return "smtp." + topLevelHost;
+        }
+    }
+
+
     public static boolean validateEmail(EditText emailAddress) {
         String email = emailAddress.getText().toString().trim();
 

+ 47 - 0
app/src/main/java/com/noahvogt/miniprojekt/data/ReadInMailsActivity.java

@@ -0,0 +1,47 @@
+package com.noahvogt.miniprojekt.data;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.noahvogt.miniprojekt.R;
+
+import java.util.List;
+
+public class ReadInMailsActivity extends AppCompatActivity {
+
+    String mEmail;
+    String mPassword;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState){
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        Intent intent = getIntent();
+        mEmail = intent.getStringExtra("Email");
+        mPassword = intent.getStringExtra("Password");
+
+        Toast.makeText(getBaseContext(),"Probe Connection ...", Toast.LENGTH_SHORT).show();
+        if (MailFunctions.canConnect(MailFunctions.getImapHostFromEmail(mEmail), mEmail, mPassword) == Boolean.TRUE) {
+            //showToast("was able to connect");
+
+            List folders = MailFunctions.listMailboxes(MailFunctions.getIMAPConnection(MailFunctions.getImapHostFromEmail(mEmail), mEmail, mPassword, 993));
+            for (int i = 0; i < folders.size(); i++) {
+                //showToast(folders.get(i).toString());
+                // TODO: select right folder to store, Synchronization
+                /*gives list of Message Objects/dictionaries */
+                //List p = MailFunctions.fetchMailsFromBox(
+                //        MailFunctions.getIMAPConnection(
+                //                MailFunctions.getImapHostFromEmail(mEmail), mEmail, mPassword),
+                //        folders.get(i).toString());
+                //System.out.println(folders.get(i).toString());
+                //System.out.println(p);
+            }
+        }
+
+    }
+}

+ 2 - 1
app/src/main/java/com/noahvogt/miniprojekt/ui/archive/ArchiveFragment.java

@@ -49,7 +49,8 @@ public class ArchiveFragment extends Fragment implements CustomAdapter.SelectedM
             adapter.submitList(messages);
             /*get List of Message to show them onClick */
             adapter.getList(messages);
-
+            /*gives list of messages to EmailViewModel */
+            MainActivity.mEmailViewModel.setListAll(messages, "Archive");
         });
 
 

+ 2 - 0
app/src/main/java/com/noahvogt/miniprojekt/ui/gallery/GalleryFragment.java

@@ -64,6 +64,8 @@ public class GalleryFragment extends Fragment implements CustomAdapter.SelectedM
             adapter.submitList(messages);
             /*get List of Message to show them onClick */
             adapter.getList(messages);
+            /*gives list of messages to EmailViewModel */
+            MainActivity.mEmailViewModel.setListAll(messages, "Sent");
         });
 
         return root;

+ 2 - 0
app/src/main/java/com/noahvogt/miniprojekt/ui/home/HomeFragment.java

@@ -53,6 +53,8 @@ public class HomeFragment extends Fragment implements CustomAdapter.SelectedMess
             adapter.submitList(messages);
             /*get List of Message to show them onClick */
             adapter.getList(messages);
+            /*gives list of messages to EmailViewModel */
+            MainActivity.mEmailViewModel.setListAll(messages, "Inbox");
 
         });
 

+ 4 - 3
app/src/main/java/com/noahvogt/miniprojekt/ui/show/MessageShowFragment.java

@@ -83,7 +83,7 @@ public class MessageShowFragment extends DialogFragment implements PopupMenu.OnM
 
         showTo = (TextView) view.findViewById(R.id.show_To);
         showFrom = (TextView) view.findViewById(R.id.show_From);
-        showSubject = (TextView) view.findViewById(R.id.show_Subject);
+        showSubject = (TextView) view.findViewById(R.id.show_subject);
         showMessage = (TextView) view.findViewById(R.id.show_Message);
         showDate = (TextView) view.findViewById(R.id.show_date);
 
@@ -145,15 +145,16 @@ public class MessageShowFragment extends DialogFragment implements PopupMenu.OnM
         switch (item.getItemId()) {
             case R.id.create_message_delete:
                 Toast.makeText(getActivity(), "item delete clicked", Toast.LENGTH_LONG).show();
+                //mEmailViewModel.deleteFolder("Inbox");
                 mEmailViewModel.deleteMessage(mCurrent);
                 return true;
             case R.id.create_message_spam:
                 Toast.makeText(getActivity(), "item spam clicked", Toast.LENGTH_LONG).show();
-                mEmailViewModel.updateMessage(mCurrent.getId(), "Spam");
+                mEmailViewModel.updateFolder(mCurrent.getId(), "Spam");
                 return true;
             case R.id.create_message_move_archive:
                 Toast.makeText(getActivity(), "item archive clicked", Toast.LENGTH_LONG).show();
-                mEmailViewModel.updateMessage(mCurrent.getId(), "Archive");
+                mEmailViewModel.updateFolder(mCurrent.getId(), "Archive");
 
 
             default: // this case should never occur

+ 2 - 0
app/src/main/java/com/noahvogt/miniprojekt/ui/slideshow/DraftFragment.java

@@ -50,6 +50,8 @@ public class  DraftFragment extends Fragment implements CustomAdapter.SelectedMe
             adapter.submitList(messages);
             /*get List of Message to show them onClick */
             adapter.getList(messages);
+            /*gives list of messages to EmailViewModel */
+            MainActivity.mEmailViewModel.setListAll(messages, "Drafts");
 
         });
 

+ 2 - 0
app/src/main/java/com/noahvogt/miniprojekt/ui/spam/SpamFragment.java

@@ -49,6 +49,8 @@ public class SpamFragment extends Fragment implements CustomAdapter.SelectedMess
             adapter.submitList(messages);
             /*get List of Message to show them onClick */
             adapter.getList(messages);
+            /*gives list of messages to EmailViewModel */
+            MainActivity.mEmailViewModel.setListAll(messages, "Spam");
 
         });
 

+ 153 - 0
app/src/main/java/com/noahvogt/miniprojekt/workers/DownloadWorker.java

@@ -0,0 +1,153 @@
+package com.noahvogt.miniprojekt.workers;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.work.Worker;
+import androidx.work.WorkerParameters;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+import com.noahvogt.miniprojekt.DataBase.Message;
+import com.noahvogt.miniprojekt.MailServerCredentials;
+import com.noahvogt.miniprojekt.MainActivity;
+import com.noahvogt.miniprojekt.data.BooleanTypeAdapter;
+import com.noahvogt.miniprojekt.data.MailFunctions;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.lang.reflect.Type;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import static com.noahvogt.miniprojekt.MainActivity.mEmailViewModel;
+import static com.noahvogt.miniprojekt.MainActivity.newMailServerCredentials;
+
+public class DownloadWorker extends Worker {
+
+    //TODO: upload every data to server
+
+    public DownloadWorker(
+            @NonNull Context appContext,
+            @NonNull WorkerParameters workerParameters){
+        super(appContext, workerParameters);
+    }
+
+    private static final String TAG = DownloadWorker.class.getSimpleName();
+
+
+    @NonNull
+    @NotNull
+    @Override
+    public Result doWork() {
+            try {
+                String mEmail = getInputData().getString(MainActivity.emailData);
+                String mPassword = getInputData().getString(MainActivity.passwordData);
+                String mName = getInputData().getString(MainActivity.nameData);
+
+                /* init custom gson with hook to parse booleans correctly */
+                GsonBuilder gsonBuilder = new GsonBuilder();
+                gsonBuilder.registerTypeAdapter(Boolean.class, new BooleanTypeAdapter());
+                Gson gson = gsonBuilder.create();
+
+                /* safe mail server login credentials */
+                newMailServerCredentials = new MailServerCredentials(
+                        mName, mEmail, mPassword, MailFunctions.getImapHostFromEmail(mEmail), MailFunctions.getSmtpHostFromEmail(mEmail), 993, 587, "");
+                String newCredentialsJson = gson.toJson(newMailServerCredentials);
+                System.out.println(newCredentialsJson);
+                MainActivity.credentialsEditor.putString("data", newCredentialsJson);
+                MainActivity.credentialsEditor.apply();
+
+                /* download all messages from mail server */
+
+                /* read login credentials from SharedPreferences */
+                SharedPreferences credentialsReader = getApplicationContext().getSharedPreferences("UserPreferences", Context.MODE_PRIVATE);
+                String readJsonData = credentialsReader.getString("data", "");
+                MailServerCredentials readMailServerCredentials = gson.fromJson(readJsonData, MailServerCredentials.class);
+
+
+                List folders =  MailFunctions.listMailboxes(MailFunctions.getIMAPConnection(newMailServerCredentials.getImapHost(),
+                        newMailServerCredentials.getUsername(), newMailServerCredentials.getPassword(), newMailServerCredentials.getImapPort()));
+
+                if (mEmailViewModel.getAll(false).size() > 0) {
+                    for (int delete = 0; delete < mEmailViewModel.getAll(false).size(); delete++) {
+                        mEmailViewModel.deleteMessage(mEmailViewModel.getAll(false).get(delete));
+                    }
+                }
+                mEmailViewModel.getAll(true);
+
+                for (int i = 0; i < folders.size(); i++) {
+                    String folderName;
+                    String folderNow = folders.get(i).toString();
+                    System.out.println("ALL Folders: " + folders);
+
+                    if (folderNow.equals("Inbox") || folderNow.equals("IBOX") || folderNow.equals("inbox")){
+                        folderName = "Inbox";
+                    }else if (folderNow.equals("Trash") || folderNow.equals("TRASH") ||
+                            folderNow.equals("Delete") || folderNow.equals("DELETE") || folderNow.equals("Papierkorb")){
+                        folderName = "Delete";
+                    } else if (folderNow.equals("Sent") ||folderNow.equals("SENT") || folderNow.equals("Gesendete Objekte")){
+                        folderName = "Sent";
+                    } else if (folderNow.equals("Archive") || folderNow.equals("ARCHIVE") || folderNow.equals("Archiv/2021") ||
+                            folderNow.equals("Archiv/2022") || folderNow.equals("Archiv/2020") ){
+                        folderName = "Archive";
+                    } else if (folderNow.equals("Draft") || folderNow.equals("Drafts") || folderNow.equals("DRAFT") ||
+                            folderNow.equals("DRAFTS") || folderNow.equals("Entw&APw-rfe")  )  {
+                        folderName = "Draft";
+                    } else if (folderNow.equals("Spam") || folderNow.equals("SPAM") || folderNow.equals("Bulk Mail")  ||
+                            folderNow.equals("DRAFTS")){
+                        folderName = "Spam";
+                    }
+                    else {
+                        folderName = folders.get(i).toString();
+                    }
+
+                    //mEmailViewModel.deleteFolder(folders.get(i).toString());
+                    /* fetch and print draft messages */
+                    String fetchedMails = MailFunctions.fetchMailsFromBox(MailFunctions.getIMAPConnection(newMailServerCredentials.getImapHost(),
+                            newMailServerCredentials.getUsername(), newMailServerCredentials.getPassword(), newMailServerCredentials.getImapPort()),
+                            folders.get(i).toString(), folderName);
+                    //System.out.println("Folder: " + folders.get(i).toString()+ "\n Foldersize: " + folders.size());
+                    //System.out.println("Fetched Mails from Folder " + folders.get(i).toString() + ": \n"+ fetchedMails + "\n MAANCBJC");
+
+                    /* parse messages in arraylist of Message class and loop through it */
+                    Type messageType = new TypeToken<ArrayList<Message>>() {
+                    }.getType();
+                    ArrayList<Message> messages = gson.fromJson(fetchedMails, messageType);
+                    for (int k = 0; k < messages.size(); k++) {
+                        Message message = messages.get(k);
+                        //System.out.println("oldDate: " + message.getDate());
+                        //SimpleDateFormat rawDate = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
+                        //SimpleDateFormat date = new SimpleDateFormat("dd.MM.yy");
+                        //Date middleDate = rawDate.parse(message.getDate());
+                        //String newDate = date.format(middleDate);
+                        //System.out.println("middle Date: " + middleDate);
+                        //System.out.println("New Date: " + newDate);
+
+                        mEmailViewModel.insert(message);
+                        //TODO: make it work
+                        /*dosent wrok idk why*/
+                        //mEmailViewModel.updateDate(message.getId(), newDate);
+                        //System.out.println("Folder: " + folders.get(i).toString() + "\n IMPORTANT FOLDERS");
+                        //System.out.println("Size of this Folder: " + messages.size());
+                    }
+
+                }
+
+
+
+
+
+                return Result.success();
+            } catch (Throwable throwable){
+                Log.e(TAG, "Error, downloading Messages", throwable);
+                return Result.failure();
+            }
+
+    }
+}

+ 102 - 136
app/src/main/python/mailFunctions.py

@@ -1,15 +1,6 @@
-import imaplib, smtplib, ssl, email, os
+import imaplib, smtplib, ssl, email, os, json
 from itertools import chain
 
-mSubject = ""
-mFrom = ""
-mCC = ""
-mBcc = ""
-mTo = ""
-mDate = ""
-mContent = ""
-output_list= []
-
 # format raw string you get from fetching mails
 def stringCompiling(inputIterable):
     # remove first nested iterables
@@ -23,7 +14,20 @@ def stringCompiling(inputIterable):
     try:
         for item in unitered:
             if item is not None:
-                nonNoneList.append(item)
+                if type(item) is not str:
+                    try:
+                        nonNoneList.append(str(item.decode("utf-8")))
+                    except UnicodeDecodeError:
+                        nonNoneList.append(str(item.decode("iso-8859-1")))
+                    except AttributeError:
+                        #print(item)
+                        #print(type(item))
+                        #print(inputIterable)
+                        #print(nonNoneList)
+                        exit()
+                else:
+                    nonNoneList.append(item)
+
     except TypeError:
         return ""
 
@@ -43,7 +47,7 @@ def checkConnection(host, username, password, port):
         connection.logout()
         return True
     except Exception as e:
-        print(str(e))
+        #print(str(e))
         return False
 
 def connect(host, username, password, port):
@@ -75,75 +79,91 @@ def listMailboxes(connection):
     connection.logout()
     return formatted_mailbox_list
 
-def fetchMails(connection, inbox, outputType):
-    print("###" + inbox + "###")
-    print(type(inbox))
+
+
+    # check that there are no bytes anymore that cannot be dumped into a json
+def verifyNoBytes(messages, output_list):
+    for messages in output_list:
+        for item in messages:
+            #print(type(item))
+            #print(item)
+            #print(messages["{}".format(item)])
+            if type(messages["{}".format(item)]) is not str:
+                print("ERROREXIT: .format failed")
+                print(messages["{}".format(item)])
+                print(type(messages["{}".format(item)]))
+
+                exit()
+            if type(item) is not str:
+                print("ERROREXIT")
+                exit()
+
+def fetchMails(connection, inbox, folderLocal):
+    #print("###" + inbox + "###")
+    #print(type(inbox))
     try:
         status, messages = connection.select(inbox)
+
     except:
         return []
+    #print("status-------\n" + status)
+    #print("messages-------\n" + str(messages))
 
-    print("status-------\n" + status)
-    print("messages-------\n" + str(messages))
     # number of top emails to fetch
     #N = 3
     # total number of emails
     messages_int = int(messages[0])
     #print("message_int------\n" + str(messages_int))
 
-    typ, data = connection.search(None, 'ALL')
-    global output_list
+    output_list = []
 
-    for num in data[0].split():
-        if outputType == "dict":
+    for seentype in ['(UNSEEN)', '(SEEN)']:
+        typ, data = connection.search(None, 'ALL', seentype)
+        for num in data[0].split():
             output_dict = {}
-        else:
-            inner_output_list = []
-
-        typ, data = connection.fetch(num, '(RFC822)')
-        msg = email.message_from_bytes(data[0][1])
-
-        #print(msg)
-        #print(num)
-
-        raw_string = email.header.decode_header(msg['Subject'])[0]
-        #print("raw_string: " + str(raw_string))
-        raw_from = email.header.decode_header(msg['From'])
-        #print("raw_from" + str(raw_from))
-        try:
-            raw_to = email.header.decode_header(msg['To'])
-        except TypeError:
-            raw_to = [""]
-        try:
-            raw_cc = email.header.decode_header(msg['CC'])
-        except TypeError:
-            raw_cc = [""]
-        try:
-            raw_bcc = email.header.decode_header(msg['BCC'])
-        except TypeError:
-            raw_bcc = [""]
-        #print("raw_to" + str(raw_to))
-        raw_date = email.header.decode_header(msg['Date'])[0]
-        #print("raw_to" + str(raw_date))
-
-        raw_msg = str(msg)
-
-        primitive_body = raw_msg[raw_msg.find('\n\n'):].strip()
-
-        #raw_body = email.header.decode_header(msg['Body'])[0][0]
-
-        # set subject to an empty string when not found
-        try:
-            if raw_string[1] == 'utf-8':
-                subject = raw_string[0].raw_string('utf-8')
-            else:
-                subject = raw_string[0]
-        except AttributeError:
-            subject=""
 
-        #print("subject: {}".format(subject))
+            typ, data = connection.fetch(num, '(RFC822)')
+
+            msg = email.message_from_bytes(data[0][1])
+
+            #print(num)
+
+            raw_string = email.header.decode_header(msg['Subject'])[0]
+            #print("raw_string: " + str(raw_string))
+            raw_from = email.header.decode_header(msg['From'])
+            #print("raw_from" + str(raw_from))
+            try:
+                raw_to = email.header.decode_header(msg['To'])
+            except TypeError:
+                raw_to = [""]
+            try:
+                raw_cc = email.header.decode_header(msg['CC'])
+            except TypeError:
+                raw_cc = [""]
+            try:
+                raw_bcc = email.header.decode_header(msg['BCC'])
+            except TypeError:
+                raw_bcc = [""]
+            #print("raw_to" + str(raw_to))
+            raw_date = email.header.decode_header(msg['Date'])[0]
+            #print("raw_to" + str(raw_date))
+
+            raw_msg = str(msg)
+
+            primitive_body = raw_msg[raw_msg.find('\n\n'):].strip()
+
+            #raw_body = email.header.decode_header(msg['Body'])[0][0]
+
+            # set subject to an empty string when not found
+            try:
+                if raw_string[1] == 'utf-8':
+                    subject = raw_string[0].raw_string('utf-8')
+                else:
+                    subject = raw_string[0].decode("iso-8859-1")
+                            #nonNoneList.append(str(item.decode("iso-8859-1")))
+            except AttributeError:
+                subject=""
 
-        if outputType == "dict":
             output_dict['subject'] = subject
             output_dict['from'] = stringCompiling(raw_from)
             output_dict['cc'] = stringCompiling(raw_cc)
@@ -151,62 +171,32 @@ def fetchMails(connection, inbox, outputType):
             output_dict['to'] = stringCompiling(raw_to)
             output_dict['date'] = stringCompiling(raw_date)
             output_dict['content'] = primitive_body
+            output_dict['folder'] = folderLocal
+            print('FolderServer: ' + inbox)
+            print('FolderLocal: ' + folderLocal)
+            print('From: ' + stringCompiling(raw_from))
+            print('Outputdictionary: ' + str(output_dict))
+
+            if seentype == '(SEEN)':
+                output_dict['seen'] = "True"
+            else:
+                output_dict['seen'] = "False"
+                # make sure the fetch command doesn't add a SEEN flag
+                connection.store(num, '-FLAGS', '(\Seen)')
 
             output_list.append(output_dict)
-        else:
-            inner_output_list.append(subject)
-            inner_output_list.append(stringCompiling(raw_from))
-            inner_output_list.append(stringCompiling(raw_cc))
-            inner_output_list.append(stringCompiling(raw_bcc))
-            inner_output_list.append(stringCompiling(raw_to))
-            inner_output_list.append(stringCompiling(raw_date))
-            inner_output_list.append(primitive_body)
-
-            output_list.append(inner_output_list)
-
-            global mSubject, mFrom, mCC, mContent, mBcc, mTo, mDate
-            print("subject " + subject)
-            mSubject = subject
-            mFrom = stringCompiling(raw_from)
-            mCC = stringCompiling(raw_cc)
-            mBcc = stringCompiling(raw_bcc)
-            mTo = stringCompiling(raw_to)
-            mDate = stringCompiling(raw_date)
-            mContent = primitive_body
+
 
 
     connection.close()
     connection.logout()
 
-    return output_list
-
-def printSubject(messageIndex):
-    print(output_list[messageIndex][0])
-    return output_list[messageIndex][0]
-
-def printFrom(messageIndex):
-    print(output_list[messageIndex][1])
-    return mFrom
-
-def printCc(messageIndex):
-    print(output_list[messageIndex][2])
-    return mCC
+    verifyNoBytes(messages, output_list)
 
-def printBcc(messageIndex):
-    print(output_list[messageIndex][3])
-    return mBcc
+    print("Finstep")
 
-def printTo(messageIndex):
-    print(output_list[messageIndex][4])
-    return mTo
+    return json.dumps(output_list)
 
-def printDate(messageIndex):
-    print(output_list[messageIndex][5])
-    return mDate
-
-def printContent(messageIndex):
-    print(output_list[messageIndex][6])
-    return mContent
 
 def sendStarttls(host, sendingMail, receivingMail, password, message="", subject="", port=587, cc=[], bcc=[]):
     context = ssl.create_default_context()
@@ -222,27 +212,3 @@ def sendStarttls(host, sendingMail, receivingMail, password, message="", subject
         serverConnection.starttls(context=context)
         serverConnection.login(sendingMail, password)
         serverConnection.sendmail(sendingMail, receivingMail, decoded)
-
-def afetchMails(con):
-    con.select("Sent")
-    status, email_ids = con.search(None, "ALL")
-    if status != 'OK':
-        raise Exception("Error running imap search for spinvox messages: "
-                        "%s" % status)
-
-    print(email_ids[0])
-    fetch_ids = ','.join(str(email_ids[0]).split())
-    status, data = con.fetch(3, '(RFC822)')
-    if status != 'OK':
-        raise Exception("Error running imap fetch for spinvox message: "
-                        "%s" % status)
-    for i in range(3,4):
-        header_msg = email.message_from_string(data[i * 3 + 0][1])
-        subject = header_msg['Subject'],
-        print(subject)
-        date = header_msg['Date'],
-        print(date)
-        body = data[i * 3 + 1][1]
-        print(body)
-    connection.close()
-    connection.logout()

+ 10 - 0
app/src/main/res/drawable/ic_baseline_call_made_24.xml

@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M9,5v2h6.59L4,18.59 5.41,20 17,8.41V15h2V5z"/>
+</vector>

+ 11 - 0
app/src/main/res/drawable/ic_baseline_call_received_24.xml

@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?attr/colorControlNormal"
+    android:autoMirrored="true">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M20,5.41L18.59,4 7,15.59V9H5v10h10v-2H8.41z"/>
+</vector>

+ 1 - 1
app/src/main/res/layout/fragment_home.xml

@@ -15,7 +15,7 @@
         android:layout_row="0"
         android:layout_height="wrap_content"
         android:layout_width="250dp"
-        android:textSize="25dp"/>
+        android:textSize="25dp" />
 
     <TextView
         android:id="@+id/message"

+ 230 - 0
app/src/main/res/layout/mail_credentials_customizer.xml

@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/textView3"
+
+        style="@style/TextAppearance.AppCompat.Widget.TextView.SpinnerItem"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="32dp"
+        android:layout_marginLeft="32dp"
+        android:layout_marginTop="32dp"
+        android:layout_marginEnd="32dp"
+        android:layout_marginRight="32dp"
+
+        android:gravity="center_horizontal"
+        android:text="Customizing Email Connection Settings"
+        android:textSize="24sp"
+
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <ScrollView
+        android:id="@+id/scrollView2"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginTop="128dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/textView3"
+        >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="vertical"
+            android:layout_marginBottom="100dp"
+            >
+
+            <com.google.android.material.textfield.TextInputLayout
+                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+                android:id="@+id/custom_mail_server_incoming_server_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="32dp"
+                android:layout_marginLeft="32dp"
+                android:layout_marginTop="32dp"
+                android:layout_marginEnd="32dp"
+                android:layout_marginRight="32dp"
+
+                android:hint="Incoming Server"
+                app:startIconDrawable="@drawable/ic_baseline_call_received_24"
+
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="parent">
+
+                <com.google.android.material.textfield.TextInputEditText
+                    android:id="@+id/custom_mail_server_incoming_server_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content" />
+            </com.google.android.material.textfield.TextInputLayout>
+
+            <com.google.android.material.textfield.TextInputLayout
+                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+                android:id="@+id/custom_mail_server_outgoing_server_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="32dp"
+                android:layout_marginLeft="32dp"
+                android:layout_marginTop="32dp"
+                android:layout_marginEnd="32dp"
+                android:layout_marginRight="32dp"
+
+                android:hint="Outgoing Server"
+                app:startIconDrawable="@drawable/ic_baseline_call_made_24"
+
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@+id/custom_mail_server_incoming_server_layout">
+
+                <com.google.android.material.textfield.TextInputEditText
+                    android:id="@+id/custom_mail_server_outgoing_server_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content" />
+            </com.google.android.material.textfield.TextInputLayout>
+
+            <com.google.android.material.textfield.TextInputLayout
+                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+                android:id="@+id/custom_mail_server_incoming_port_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="32dp"
+                android:layout_marginLeft="32dp"
+                android:layout_marginTop="32dp"
+                android:layout_marginEnd="32dp"
+                android:layout_marginRight="32dp"
+
+                android:hint="Incoming Port"
+                app:startIconDrawable="@drawable/ic_baseline_call_received_24"
+
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@+id/custom_mail_server_outgoing_server_layout">
+
+                <com.google.android.material.textfield.TextInputEditText
+                    android:id="@+id/custom_mail_server_incoming_port_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content" />
+            </com.google.android.material.textfield.TextInputLayout>
+
+            <com.google.android.material.textfield.TextInputLayout
+                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+                android:id="@+id/custom_mail_server_outgoing_port_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="32dp"
+                android:layout_marginLeft="32dp"
+                android:layout_marginTop="32dp"
+                android:layout_marginEnd="32dp"
+                android:layout_marginRight="32dp"
+
+                android:hint="Outgoing Port"
+                app:startIconDrawable="@drawable/ic_baseline_call_made_24"
+
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@+id/custom_mail_server_incoming_port_layout">
+
+                <com.google.android.material.textfield.TextInputEditText
+                    android:id="@+id/custom_mail_server_outgoing_port_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content" />
+            </com.google.android.material.textfield.TextInputLayout>
+
+            <com.google.android.material.textfield.TextInputLayout
+                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+                android:id="@+id/custom_mail_server_username_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="32dp"
+                android:layout_marginLeft="32dp"
+                android:layout_marginTop="32dp"
+                android:layout_marginEnd="32dp"
+                android:layout_marginRight="32dp"
+
+                android:hint="Server Username"
+                app:startIconDrawable="@drawable/ic_mail_outline"
+
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@+id/custom_mail_server_outgoing_port_layout">
+
+                <com.google.android.material.textfield.TextInputEditText
+                    android:id="@+id/custom_mail_server_username_text"
+                    android:inputType="textEmailAddress"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content" />
+            </com.google.android.material.textfield.TextInputLayout>
+
+            <com.google.android.material.textfield.TextInputLayout
+                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+                android:id="@+id/custom_mail_server_password_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="32dp"
+                android:layout_marginLeft="32dp"
+                android:layout_marginTop="32dp"
+                android:layout_marginEnd="32dp"
+                android:layout_marginRight="32dp"
+
+                android:hint="Server Password"
+                app:startIconDrawable="@drawable/ic_lock"
+
+                android:paddingBottom="50dp"
+
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@+id/custom_mail_server_username_layout">
+
+                <com.google.android.material.textfield.TextInputEditText
+                    android:id="@+id/custom_mail_server_password_text"
+                    android:inputType="textPassword"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content" />
+            </com.google.android.material.textfield.TextInputLayout>
+
+            <RelativeLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+
+                <Button
+                    android:id="@+id/cancelCustomizeButton"
+
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+
+                    android:layout_alignParentLeft="true"
+                    android:layout_centerVertical="true"
+                    android:layout_marginStart="42dp"
+                    android:layout_marginLeft="42dp"
+                    android:text="Save" />
+
+                <Button
+                    android:id="@+id/saveCustomizeButton"
+
+                    android:layout_marginEnd="42dp"
+                    android:layout_marginRight="42dp"
+
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_alignBottom="@+id/cancelCustomizeButton"
+                    android:layout_alignParentRight="true"
+                    android:text="Cancel" />
+
+            </RelativeLayout>
+
+        </LinearLayout>
+
+
+    </ScrollView>
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 75 - 20
app/src/main/res/layout/message_show_fragment.xml

@@ -71,7 +71,8 @@
             android:orientation="vertical"
             android:gravity="top">
 
-            <LinearLayout
+
+            <GridLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:background="@drawable/textview_border"
@@ -83,22 +84,39 @@
                 android:layout_marginRight="12dp"
                 android:layout_marginBottom="12dp">
 
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_row="0"
+                    android:layout_column="0"
+
+                    android:layout_marginStart="12dp"
+                    android:layout_marginLeft="12dp"
+                    android:layout_marginTop="12dp"
+                    android:layout_marginEnd="12dp"
+                    android:layout_marginRight="12dp"
+                    android:layout_marginBottom="12dp"
+                    android:text="@string/show_from"
+                    android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
+
 
                 <TextView
                     android:id="@+id/show_From"
-                    android:layout_width="match_parent"
+                    android:layout_width="288dp"
                     android:layout_height="wrap_content"
-                    android:textAppearance="@style/TextAppearance.AppCompat.Body1"
-
                     android:layout_marginStart="12dp"
                     android:layout_marginLeft="12dp"
+
                     android:layout_marginTop="12dp"
                     android:layout_marginEnd="12dp"
                     android:layout_marginRight="12dp"
-                    android:layout_marginBottom="12dp"/>
-            </LinearLayout>
+                    android:layout_marginBottom="12dp"
+                    android:hint="@string/show_from"
+                    android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
 
-            <LinearLayout
+            </GridLayout>
+
+            <GridLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:background="@drawable/textview_border"
@@ -111,21 +129,39 @@
                 android:layout_marginBottom="12dp">
 
                 <TextView
-                    android:id="@+id/show_To"
-                    android:layout_width="match_parent"
+                    android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
+                    android:layout_row="0"
+                    android:layout_column="0"
+
                     android:layout_marginStart="12dp"
-                    android:textAppearance="@style/TextAppearance.AppCompat.Body1"
+                    android:layout_marginLeft="12dp"
+                    android:layout_marginTop="12dp"
+                    android:layout_marginEnd="12dp"
+                    android:layout_marginRight="12dp"
+                    android:layout_marginBottom="12dp"
+                    android:text="@string/show_To"
+                    android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
+
 
+                <TextView
+                    android:id="@+id/show_To"
+                    android:layout_width="306dp"
+                    android:layout_height="wrap_content"
+                    android:layout_marginStart="12dp"
                     android:layout_marginLeft="12dp"
+
                     android:layout_marginTop="12dp"
                     android:layout_marginEnd="12dp"
                     android:layout_marginRight="12dp"
-                    android:layout_marginBottom="12dp" />
-            </LinearLayout>
+                    android:layout_marginBottom="12dp"
+                    android:hint="@string/show_To"
+                    android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
 
+            </GridLayout>
 
-            <LinearLayout
+
+            <GridLayout
                 android:background="@drawable/textview_border"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
@@ -139,18 +175,36 @@
 
 
                 <TextView
-                    android:id="@+id/show_Subject"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:textAppearance="@style/TextAppearance.AppCompat.Body1"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_row="0"
+                    android:layout_column="0"
 
                     android:layout_marginStart="12dp"
                     android:layout_marginLeft="12dp"
                     android:layout_marginTop="12dp"
                     android:layout_marginEnd="12dp"
                     android:layout_marginRight="12dp"
-                    android:layout_marginBottom="12dp"/>
-            </LinearLayout>
+                    android:layout_marginBottom="12dp"
+                    android:text="@string/show_subject"
+                    android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
+
+
+                <TextView
+                    android:id="@+id/show_subject"
+                    android:layout_width="280dp"
+                    android:layout_height="wrap_content"
+                    android:layout_marginStart="12dp"
+                    android:layout_marginLeft="12dp"
+
+                    android:layout_marginTop="12dp"
+                    android:layout_marginEnd="12dp"
+                    android:layout_marginRight="12dp"
+                    android:layout_marginBottom="12dp"
+                    android:hint="@string/show_subject"
+                    android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
+
+            </GridLayout>
 
             <GridLayout
                 android:layout_width="wrap_content"
@@ -203,7 +257,7 @@
 
                 <TextView
                     android:id="@+id/show_date"
-                    android:layout_width="wrap_content"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
 
                     android:layout_column="1"
@@ -235,6 +289,7 @@
                     android:layout_height="wrap_content"
                     android:minHeight="200dp"
                     android:textAppearance="@style/TextAppearance.AppCompat.Body1"
+                    android:hint="@string/show_message"
 
                     android:layout_marginStart="12dp"
                     android:layout_marginLeft="12dp"

+ 0 - 2
app/src/main/res/layout/popup.xml

@@ -84,9 +84,7 @@
 
         <com.google.android.material.textfield.TextInputEditText
             android:id="@id/popup_material_name_asking_text"
-
             android:inputType="textPersonName"
-
             android:layout_width="match_parent"
             android:layout_height="wrap_content" />
     </com.google.android.material.textfield.TextInputLayout>

+ 46 - 0
app/src/main/res/layout/welcome.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+
+    <TextView
+        android:id="@+id/backgroun"
+        android:layout_width="321dp"
+        android:layout_height="596dp"
+        android:gravity="center_horizontal"
+
+        android:text="@string/text_welcome"
+        android:textAlignment="center"
+        android:textAppearance="@style/TextAppearance.AppCompat.Body1"
+        android:textSize="@dimen/text_size_welcome"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.495"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.142" />
+
+    <Button
+        android:id="@+id/okay_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+
+        android:layout_marginEnd="16dp"
+
+        android:layout_marginRight="16dp"
+        android:layout_marginBottom="36dp"
+        android:text="@string/text_ok"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.524"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/backgroun"
+        app:layout_constraintVertical_bias="0.937"
+        tools:ignore="MissingConstraints" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 9 - 2
app/src/main/res/menu/main.xml

@@ -2,8 +2,15 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
     <item
-        android:id="@+id/action_settings"
+        android:id="@+id/action_information"
+        android:title="@string/action_information"/>
+    <item
+        android:id="@+id/action_deletefolder"
         android:orderInCategory="100"
-        android:title="@string/action_settings"
+        android:title="@string/action_deleteFolder"
         app:showAsAction="never" />
+    <item
+        android:id="@+id/action_refresh"
+        android:title="@string/action_refresh"/>
+
 </menu>

+ 1 - 0
app/src/main/res/values/dimens.xml

@@ -8,4 +8,5 @@
 
     <dimen name="list_item_height">45dp</dimen>
     <dimen name="margin_medium">30dp</dimen>
+    <dimen name="text_size_welcome">22sp</dimen>
 </resources>

+ 25 - 3
app/src/main/res/values/strings.xml

@@ -5,7 +5,10 @@
     <string name="nav_header_title">Max Mustermann</string>
     <string name="nav_header_subtitle">max@mustermann.com</string>
     <string name="nav_header_desc">Navigation header</string>
-    <string name="action_settings">Settings</string>
+
+    <string name="action_deleteFolder">Delete all Folders</string>
+    <string name="action_refresh">Refresh</string>
+    <string name="action_information">Information</string>
 
     <string name="drawer_inbox">Inbox</string>
     <string name="drawer_sent">Sent</string>
@@ -19,8 +22,8 @@
     <string name="your_full_name_filler">Your Full Name</string>
 
 
-    <string name="show_from">From</string>
-    <string name="show_To">To </string>
+    <string name="show_from">From:</string>
+    <string name="show_To">To: </string>
     <string name="show_subject">Subject</string>
     <string name="show_message">Message</string>
     <string name="show_cc">See CC</string>
@@ -44,6 +47,25 @@
     <string name="text_save">Save</string>
     <string name="text_cancel">Cancel</string>
     <string name="text_create_message">Create Message</string>
+    <string name="text_ok">Okay</string>
+
+    <string name="text_welcome">
+        Hello friendly user. \n
+        When creating an account,
+        all your messages will be downloaded and
+        \n  you may experience slower performance of the app.
+        When you create a new account, \n
+        you need to open all your folders once \n
+        in order to not find any emails
+        from the old account
+        \n afterwards.
+        \n It is the same for the option "Delete All Folders".
+        \n This is a bug which could not be fixed yet.
+        We wish you a lot of fun with our app.
+        \n \n
+        This app is in alpha version and created as part of a school project.
+        Our app is fully available on Github.
+    </string>
 
     <!--  hint -->
     <string name="hint_email_from">From (Email)</string>

+ 0 - 32
patches/intent.patch

@@ -1,32 +0,0 @@
-diff --git a/app/src/main/java/com/noahvogt/miniprojekt/messageCreateFragment.java b/app/src/main/java/com/noahvogt/miniprojekt/messageCreateFragment.java
-index e36c97e..3afc5e5 100644
---- a/app/src/main/java/com/noahvogt/miniprojekt/messageCreateFragment.java
-+++ b/app/src/main/java/com/noahvogt/miniprojekt/messageCreateFragment.java
-@@ -6,6 +6,7 @@ import android.content.SharedPreferences;
- 
- import android.content.DialogInterface;
- import android.content.Intent;
-+import android.net.Uri;
- import android.os.Bundle;
- import android.os.Message;
- import android.text.TextUtils;
-@@ -21,6 +22,7 @@ import android.widget.Toast;
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
- import androidx.appcompat.app.AlertDialog;
-+import androidx.appcompat.widget.ActivityChooserView;
- import androidx.fragment.app.DialogFragment;
- 
- import java.util.concurrent.ExecutorService;
-@@ -194,6 +196,11 @@ public class messageCreateFragment extends DialogFragment implements PopupMenu.O
-                 if (mailFunctions.validateMessageBody(messageBodyObject) && mailFunctions.validateSubject(subjectObject) &&
-                 mailFunctions.validateEmail(receivingAddressObject) && mailFunctions.validateEmail(sendingAddressObject) &&
-                 !mailFunctions.checkForSameEmail(sendingAddressObject, receivingAddressObject)) {
-+                    /* send email */
-+                    Intent intent = new Intent(Intent.ACTION_VIEW,
-+                            Uri.parse("mailto:" + receivingAddress));
-+                    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
-+                    intent.putExtra(Intent.EXTRA_TEXT, messageBody);
-                     Toast.makeText(getActivity(), "sending ... ", Toast.LENGTH_SHORT).show();
-                     dismiss();
-                 } else {

+ 0 - 110
tests/mailFunctions.py

@@ -1,110 +0,0 @@
-import imaplib, email, os
-
-def errorMsgExit(error_msg):
-    print("Error: " + error_msg)
-
-def checkConnection(host, username, password, port):
-    try:
-        connection = imaplib.IMAP4_SSL(host, port)
-        connection.login(username, password)
-        connection.logout()
-        return True
-    except Exception as e:
-        print(str(e))
-        return False
-
-def connect(host, username, password, port):
-    connect = imaplib.IMAP4_SSL(host, port)
-    connect.login(username, password)
-    connect.enable("UTF8=ACCEPT")
-    return connect
-
-def listMailboxes(connection):
-    mailboxes = connection.list()
-    formatted_mailbox_list = []
-
-    for items in mailboxes:
-        if type(items) == list:
-            for raw_box_string in items:
-                box_string = str(raw_box_string)
-                # TODO: handle cases when folder contains subfolders
-                modified_box_string = (box_string[box_string.find('"/" ')+4:-1])
-
-                # strip unneeded "'s surrounding the folder name
-                if modified_box_string.startswith('"') and modified_box_string.endswith('"'):
-                    modified_box_string = modified_box_string[1:-1]
-
-                formatted_mailbox_list.append(modified_box_string)
-
-    connection.logout()
-    return formatted_mailbox_list
-
-def fetchMails(connection, inbox):
-    status, messages = connection.select(inbox)
-    print("status-------\n" + status)
-    print("messages-------\n" + str(messages))
-    # number of top emails to fetch
-    N = 3
-    # total number of emails
-    messages_int = int(messages[0])
-    print("message_int------\n" + str(messages_int))
-
-    typ, data = connection.search(None, 'ALL')
-    output_list = []
-    for num in data[0].split():
-        typ, data = connection.fetch(num, '(RFC822)')
-        msg = email.message_from_bytes(data[0][1])
-        #print(type(msg))
-        #print(msg)
-        raw_subject = email.header.decode_header(msg['Subject'])[0]
-        #raw_body = email.header.decode_header(msg['Body'])[0][0]
-        '''
-        if decode[1] == 'utf-8':
-            subject = decode[0].decode('utf-8')
-        else:
-            subject = decode[0]
-        '''
-        #print("subject: {}".format(subject))
-        #input()
-        #print('Message %s\n%s\n' % (num, data[0][1]))
-        #print('Message %s\n%s\n' % (num, data[0][1].split()))
-        #print('%s\n' % (len(data[0][1].split())))
-        '''
-        j = 0
-        for i in range(len(str(msg))):
-            if str(msg)[i] == "\n":
-                print(str(msg)[j:i])
-                j = int(i)
-        '''
-
-
-        output_list.append(str(raw_subject))
-
-    connection.close()
-    connection.logout()
-
-    return output_list
-
-def afetchMails(con):
-    con.select("Sent")
-    status, email_ids = con.search(None, "ALL")
-    if status != 'OK':
-        raise Exception("Error running imap search for spinvox messages: "
-                        "%s" % status)
-
-    print(email_ids[0])
-    fetch_ids = ','.join(str(email_ids[0]).split())
-    status, data = con.fetch(3, '(RFC822)')
-    if status != 'OK':
-        raise Exception("Error running imap fetch for spinvox message: "
-                        "%s" % status)
-    for i in range(3,4):
-        header_msg = email.message_from_string(data[i * 3 + 0][1])
-        subject = header_msg['Subject'],
-        print(subject)
-        date = header_msg['Date'],
-        print(date)
-        body = data[i * 3 + 1][1]
-        print(body)
-    connection.close()
-    connection.logout()