Skip to content
Permalink
Browse files

solve bug 0000397

  • Loading branch information...
domjos1994 committed Oct 25, 2019
1 parent a7a0f91 commit 9c0b11641d26c5edcb86339cdc3e1ebe53fbde82
Showing with 563 additions and 90 deletions.
  1. +3 −0 app/build.gradle
  2. +9 −23 app/src/main/AndroidManifest.xml
  3. +43 −11 app/src/main/java/de/domjos/unitrackermobile/activities/AccountActivity.java
  4. +197 −0 app/src/main/java/de/domjos/unitrackermobile/activities/CalendarActivity.java
  5. +3 −0 app/src/main/java/de/domjos/unitrackermobile/activities/MainActivity.java
  6. +42 −0 app/src/main/java/de/domjos/unitrackermobile/custom/CustomEventDay.java
  7. +67 −3 app/src/main/java/de/domjos/unitrackermobile/helper/SQLiteGeneral.java
  8. +9 −0 app/src/main/res/drawable/ic_perm_contact_calendar_black_24dp.xml
  9. +14 −0 app/src/main/res/layout/account_activity.xml
  10. +49 −0 app/src/main/res/layout/calendar_activity.xml
  11. +4 −0 app/src/main/res/menu/nav_main.xml
  12. +2 −1 app/src/main/res/raw/init.sql
  13. +3 −0 app/src/main/res/values-de/strings.xml
  14. +3 −0 app/src/main/res/values/strings.xml
  15. +1 −1 build.gradle
  16. +1 −1 unitrackerlibrary/src/main/AndroidManifest.xml
  17. +8 −0 ...ibrary/src/main/java/de/domjos/unitrackerlibrary/services/authentication/AccessTokenProvider.java
  18. +47 −0 ...ibrary/src/main/java/de/domjos/unitrackerlibrary/services/authentication/GithubTokenProvider.java
  19. +15 −0 unitrackerlibrary/src/main/java/de/domjos/unitrackerlibrary/services/engine/Authentication.java
  20. +40 −14 unitrackerlibrary/src/main/java/de/domjos/unitrackerlibrary/services/engine/JSONEngine.java
  21. +3 −36 unitrackerlibrary/src/main/java/de/domjos/unitrackerlibrary/services/tracker/Github.java
@@ -79,12 +79,15 @@ dependencies {
implementation 'com.github.angads25:filepicker:1.1.1'
implementation 'com.github.takusemba:spotlight:1.8.0'
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0-alpha'
implementation 'com.applandeo:material-calendar-view:1.7.0'

// test libraries
implementation 'androidx.appcompat:appcompat:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

implementation project(path: ':unitrackerlibrary')
implementation 'androidx.work:work-runtime:2.2.0'
}
@@ -1,22 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2019 Domjos
~ This file is part of UniTrackerMobile <https://github.com/domjos1994/UniTrackerMobile>.
~
~ UniTrackerMobile is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ UniTrackerMobile is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with UniTrackerMobile. If not, see <http://www.gnu.org/licenses/>.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
xmlns:tools="http://schemas.android.com/tools"
@@ -29,18 +11,22 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
android:name="androidx.multidex.MultiDexApplication"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
android:name="androidx.multidex.MultiDexApplication"
tools:targetApi="m">

<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-4983888966373182~7705161676" />
<activity
android:name=".activities.CalendarActivity"
android:label="@string/calendar"
android:parentActivityName=".activities.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="de.domjos.unitrackermobile.activities.MainActivity" />
</activity>

<activity
android:name=".activities.StatisticsActivity"
@@ -39,11 +39,11 @@
import com.google.android.material.bottomnavigation.BottomNavigationView;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import de.domjos.unitrackerlibrary.interfaces.IBugService;
import de.domjos.unitrackerlibrary.model.ListObject;
import de.domjos.unitrackerlibrary.services.authentication.GithubTokenProvider;
import de.domjos.unitrackerlibrary.services.engine.Authentication;
import de.domjos.unitrackerlibrary.utils.Converter;
import de.domjos.unitrackerlibrary.utils.MessageHelper;
@@ -57,8 +57,9 @@

public final class AccountActivity extends AbstractActivity {
private SwipeRefreshDeleteList lvAccounts;
private Spinner cmbAccountTracker;
private Spinner cmbAccountTracker, cmbAccountAuthentication;
private ArrayAdapter<Authentication.Tracker> trackerAdapter;
private ArrayAdapter<Authentication.Auth> authAdapter;
private EditText txtAccountServer, txtAccountUserName, txtAccountPassword,
txtAccountAPI, txtAccountImageURL, txtAccountDescription, txtAccountExtended;
private AutoCompleteTextView txtAccountTitle;
@@ -112,6 +113,7 @@ public void onItemSelected(AdapterView<?> parent, View view, int position, long

Authentication.Tracker item = trackerAdapter.getItem(position);
if (item != null) {
fillAuthByTracker(item);
switch (item) {
case Local:
txtAccountServer.setText(Authentication.Tracker.Local.name());
@@ -270,6 +272,12 @@ protected void initControls() {

new Thread(() -> {
try {
if(!chkAccountGuest.isChecked()) {
if(currentAccount.getAuthentication() == Authentication.Auth.OAUTH) {
GithubTokenProvider githubTokenProvider = new GithubTokenProvider(currentAccount);
currentAccount.setAPIKey(githubTokenProvider.refreshToken());
}
}
IBugService bugService = Helper.getCurrentBugService(this.currentAccount, this.getApplicationContext());
if (chkAccountGuest.isChecked() || bugService.testConnection()) {
AccountActivity.this.runOnUiThread(() -> {
@@ -306,19 +314,17 @@ protected void initControls() {
});

this.lvAccounts = this.findViewById(R.id.lvAccounts);
this.cmbAccountTracker = this.findViewById(R.id.cmbAccountTracker);

// disable github
List<Authentication.Tracker> trackers = new LinkedList<>();
for(Authentication.Tracker tracker : Authentication.Tracker.values()) {
if(tracker!= Authentication.Tracker.Github) {
trackers.add(tracker);
}
}
this.trackerAdapter = new ArrayAdapter<>(this.getApplicationContext(), R.layout.spinner_item, trackers);
this.cmbAccountTracker = this.findViewById(R.id.cmbAccountTracker);
this.trackerAdapter = new ArrayAdapter<>(this.getApplicationContext(), R.layout.spinner_item, Authentication.Tracker.values());
this.cmbAccountTracker.setAdapter(this.trackerAdapter);
this.trackerAdapter.notifyDataSetChanged();

this.cmbAccountAuthentication = this.findViewById(R.id.cmbAccountAuthentication);
this.authAdapter = new ArrayAdapter<>(this.getApplicationContext(), R.layout.spinner_item);
this.cmbAccountAuthentication.setAdapter(this.authAdapter);
this.authAdapter.notifyDataSetChanged();

this.chkAccountGuest = this.findViewById(R.id.chkAccountGuest);
this.txtAccountTitle = this.findViewById(R.id.txtAccountTitle);
List<Authentication.Tracker> ls = Arrays.asList(Authentication.Tracker.values());
@@ -337,6 +343,25 @@ protected void initControls() {
OnBoardingHelper.tutorialStep2(AccountActivity.this, () -> this.manageControls(true, true, false), this.findViewById(R.id.tblControls));
}

private void fillAuthByTracker(Authentication.Tracker tracker) {
this.authAdapter.clear();
this.authAdapter.addAll(Authentication.Auth.values());
switch (tracker) {
case MantisBT:
this.authAdapter.remove(Authentication.Auth.OAUTH);
this.authAdapter.remove(Authentication.Auth.API_KEY);
break;
case YouTrack:
this.authAdapter.remove(Authentication.Auth.OAUTH);
this.authAdapter.remove(Authentication.Auth.Basic);
break;
case Github:
this.authAdapter.remove(Authentication.Auth.Basic);
this.authAdapter.remove(Authentication.Auth.API_KEY);
break;
}
}

@Override
protected void initValidators() {
this.accountValidator = new Validator(this.getApplicationContext());
@@ -377,6 +402,7 @@ protected void manageControls(boolean editMode, boolean reset, boolean selected)
this.txtAccountDescription.setEnabled(editMode);
this.cmdAccountImageGallery.setEnabled(editMode);
this.cmbAccountTracker.setEnabled(editMode);
this.cmbAccountAuthentication.setEnabled(editMode);
this.chkAccountGuest.setEnabled(editMode);
this.txtAccountExtended.setEnabled(editMode);

@@ -403,6 +429,11 @@ private void objectToControls() {
this.cmbAccountTracker.setSelection(this.trackerAdapter.getPosition(Authentication.Tracker.Local));
this.txtAccountServer.setText(Authentication.Tracker.Local.name());
}
if (this.currentAccount.getAuthentication() !=null) {
this.cmbAccountAuthentication.setSelection(this.authAdapter.getPosition(this.currentAccount.getAuthentication()));
} else {
this.cmbAccountAuthentication.setSelection(this.authAdapter.getPosition(Authentication.Auth.Basic));
}
if (this.currentAccount.getCover() != null) {
Bitmap bitmap = BitmapFactory.decodeByteArray(this.currentAccount.getCover(), 0, this.currentAccount.getCover().length);
this.cmdAccountImageGallery.setImageBitmap(bitmap);
@@ -426,6 +457,7 @@ private void controlsToObject() {
this.currentAccount.setDescription(this.txtAccountDescription.getText().toString());
this.currentAccount.setTracker(this.trackerAdapter.getItem(this.cmbAccountTracker.getSelectedItemPosition()));
this.currentAccount.setGuest(this.chkAccountGuest.isChecked());
this.currentAccount.setAuthentication(this.authAdapter.getItem(this.cmbAccountAuthentication.getSelectedItemPosition()));
if (this.cmdAccountImageGallery.getDrawable() instanceof BitmapDrawable) {
this.currentAccount.setCover(Converter.convertDrawableToByteArray(this.cmdAccountImageGallery.getDrawable()));
} else {
@@ -0,0 +1,197 @@
package de.domjos.unitrackermobile.activities;

import android.content.Intent;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.applandeo.materialcalendarview.CalendarUtils;
import com.applandeo.materialcalendarview.CalendarView;
import com.applandeo.materialcalendarview.EventDay;

import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import de.domjos.unitrackerlibrary.interfaces.IBugService;
import de.domjos.unitrackerlibrary.model.issues.Issue;
import de.domjos.unitrackerlibrary.model.objects.DescriptionObject;
import de.domjos.unitrackerlibrary.model.projects.Project;
import de.domjos.unitrackerlibrary.model.projects.Version;
import de.domjos.unitrackerlibrary.services.engine.Authentication;
import de.domjos.unitrackerlibrary.tasks.AbstractTask;
import de.domjos.unitrackerlibrary.tasks.IssueTask;
import de.domjos.unitrackerlibrary.tasks.ProjectTask;
import de.domjos.unitrackerlibrary.tasks.VersionTask;
import de.domjos.unitrackerlibrary.utils.MessageHelper;
import de.domjos.unitrackermobile.R;
import de.domjos.unitrackermobile.custom.AbstractActivity;
import de.domjos.unitrackermobile.custom.CustomEventDay;
import de.domjos.unitrackermobile.helper.Helper;

public class CalendarActivity extends AbstractActivity {
private CalendarView calendarView;
private ProgressBar progressBar;
private LinearLayout llToObject;
private TextView lblCalendarTitle, lblCalendarSubTitle;
private List<EventDay> eventDays;
private Intent intent;


public CalendarActivity() {
super(R.layout.calendar_activity);
}

@Override
protected void initActions() {
this.calendarView.setOnDayClickListener(eventDay -> {
if(eventDay instanceof CustomEventDay) {
CustomEventDay customEventDay = (CustomEventDay) eventDay;

this.lblCalendarSubTitle.setText(customEventDay.getDescriptionObject().getTitle());
if(customEventDay.getDescriptionObject() instanceof Project) {
this.lblCalendarTitle.setText(this.getString(R.string.projects));
this.intent = new Intent(this.getApplicationContext(), ProjectActivity.class);
} else if(customEventDay.getDescriptionObject() instanceof Version) {
this.lblCalendarTitle.setText(this.getString(R.string.versions));
this.intent = new Intent(this.getApplicationContext(), VersionActivity.class);
} else if(customEventDay.getDescriptionObject() instanceof Issue) {
this.lblCalendarTitle.setText(this.getString(R.string.issues));
this.intent = new Intent(this.getApplicationContext(), MainActivity.class);
} else {
this.lblCalendarTitle.setText(this.getString(R.string.calendar));
this.intent = null;
}

}
});

this.llToObject.setOnClickListener(view -> {
if(intent!=null) {
startActivity(intent);
}
});
}

@Override
protected void initControls() {
this.calendarView = this.findViewById(R.id.cvEventCalendar);
this.progressBar = this.findViewById(R.id.pbCalendar);

this.llToObject = this.findViewById(R.id.llToObject);
this.lblCalendarTitle = this.findViewById(R.id.lblCalendarTitle);
this.lblCalendarSubTitle = this.findViewById(R.id.lblCalendarSubTitle);
}

@Override
protected void reload() {
this.insertEvents();
}

private void insertEvents() {
try {
this.progressBar.setVisibility(View.VISIBLE);
List<Authentication> accounts = MainActivity.GLOBALS.getSqLiteGeneral().getAccounts("");
this.eventDays = new LinkedList<>();
for(Authentication account : accounts) {
IBugService bugService = Helper.getCurrentBugService(account, this.getApplicationContext());

ProjectTask projectTask = new ProjectTask(CalendarActivity.this, bugService, false, false, R.drawable.ic_apps_black_24dp);
projectTask.after(new AbstractTask.PostExecuteListener() {
@Override
public void onPostExecute(Object o) {
if(o instanceof List) {
List objects = (List) o;
for (Object obj : objects) {
if(obj instanceof Project) {
Project project = (Project) obj;
addEvent(project.getReleasedAt(), project.getTitle(), project);

VersionTask versionTask = new VersionTask(CalendarActivity.this, bugService, project.getId(), false, false, "versions", R.drawable.ic_update_black_24dp);
versionTask.after(new AbstractTask.PostExecuteListener() {
@Override
public void onPostExecute(Object o) {
List objList = (List) o;
for(Object obj : objList) {
Version version = (Version) obj;
addEvent(version.getReleasedVersionAt(), String.format("%s: %s", project.getTitle(), version.getTitle()), version);
}
}
});
versionTask.execute(0);

IssueTask issueTask = new IssueTask(CalendarActivity.this, bugService, project.getId(), false, false, false, R.drawable.ic_bug_report_black_24dp);
issueTask.after(new AbstractTask.PostExecuteListener() {
@Override
public void onPostExecute(Object o) {
List objList = (List) o;
loadingFinish(0, objList.size());
int i = 0;
for(Object obj : objList) {
Issue issue = (Issue) obj;

IssueTask detailTasks = new IssueTask(CalendarActivity.this, bugService, project.getId(), false, true, false, R.drawable.ic_bug_report_black_24dp);
detailTasks.after(new AbstractTask.PostExecuteListener() {
@Override
public void onPostExecute(Object o) {
List obj = (List) o;
Issue detailIssue = (Issue) obj.get(0);
if(detailIssue.getDueDate() != null) {
addEvent(detailIssue.getDueDate().getTime(), String.format("%s: %s", project.getTitle(), detailIssue.getTitle()), detailIssue);
}
}
});
detailTasks.execute(issue.getId());
i++;
loadingFinish(i, objList.size());
}
}
});
issueTask.execute(0);
}
}
}
}
});
projectTask.execute(0);
}
} catch (Exception ex) {
MessageHelper.printException(ex, CalendarActivity.this);
}
}

private void loadingFinish(int current, int max) {
this.progressBar.setMax(max);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
this.progressBar.setProgress(current, true);
} else {
this.progressBar.setProgress(current);
}
if(current==max) {
this.progressBar.setVisibility(View.GONE);
} else {
this.progressBar.setVisibility(View.VISIBLE);
}
this.progressBar.invalidate();
}


private void addEvent(long time, String title, DescriptionObject descriptionObject) {
Calendar calendar = Calendar.getInstance();
Date dt = new Date();
dt.setTime(time);
calendar.setTime(dt);

Drawable drawable = CalendarUtils.getDrawableText(this.getApplicationContext(), title, Typeface.DEFAULT_BOLD, R.color.colorPrimary, 14);
CustomEventDay customEventDay = new CustomEventDay(calendar, drawable, R.color.colorPrimary);
customEventDay.setDescriptionObject(descriptionObject);
this.eventDays.add(customEventDay);
this.calendarView.setEvents(this.eventDays);
this.calendarView.invalidate();
}
}

0 comments on commit 9c0b116

Please sign in to comment.
You can’t perform that action at this time.