Skip to content
Snippets Groups Projects
Commit 38c2d95b authored by Michi302's avatar Michi302
Browse files

Merge branch 'master' into fdroid

# Conflicts:
#	.gitlab-ci.yml
#	.magnum.yml
#	app/build.gradle
#	app/src/main/AndroidManifest.xml
#	app/src/main/java/com/commit451/gitlab/GitLabApp.java
parents 0216e5f3 d79d79f5
No related branches found
No related tags found
No related merge requests found
Pipeline #
Showing
with 1421 additions and 686 deletions
before_script:
- unset DISPLAY
- export TERM=dumb
- export _JAVA_OPTIONS="-Djava.awt.headless=true"
- apt-get -q -y update
- apt-get -q -y install wget tar openjdk-7-jdk lib32stdc++6 lib32z1
- wget -q http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
- tar xvzf android-sdk_r24.4.1-linux.tgz
- echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter tools,platform-tools,build-tools-23.0.2,android-23,extra-android-m2repository
- tar xzf android-sdk_r24.4.1-linux.tgz
- echo y | android-sdk-linux/tools/android -s update sdk --no-ui --all --filter tools,platform-tools,build-tools-23.0.2,android-23,extra-android-m2repository
- export ANDROID_HOME=$PWD/android-sdk-linux
- chmod +x prepare-build.sh
- ./prepare-build.sh
- chmod +x gradlew
 
test:
build:
script:
- ./gradlew build
- ./gradlew build --stacktrace
before_script:
- wget http://dl.google.com/android/android-sdk_r24.4-macosx.zip
- tar xvzf android-sdk_r24.4-macosx.zip
- cd android-sdk-macosx/
- ./tools/android update sdk --no-ui tools,platform-tools,build-tools-23.0.1,android-23,extra-android-m2repository
- chmod +x scripts/prepare-build.sh
- ./prepare-build.sh
- unset DISPLAY
- export TERM=dumb
- export _JAVA_OPTIONS="-Djava.awt.headless=true"
- sudo apt-get -q -y update
- sudo apt-get -q -y install wget tar openjdk-7-jdk lib32stdc++6 lib32z1
- wget -q http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
- tar xzf android-sdk_r24.4.1-linux.tgz
- echo y | android-sdk-linux/tools/android -s update sdk --no-ui --all --filter tools,platform-tools,build-tools-23.0.2,android-23,extra-android-m2repository
- export ANDROID_HOME=$PWD/android-sdk-linux
- chmod +x gradlew
 
script:
- ./gradlew build
- ./gradlew build --stacktrace
language: android
android:
components:
# Uncomment the lines below if you want to
# use the latest revision of Android SDK Tools
- platform-tools
- tools
# The BuildTools version used by your project
- build-tools-23.0.1
# The SDK version used to compile your project
- platform-tools
- build-tools-23.0.2
- android-23
# Additional components
# - extra-google-google_play_services
# - extra-google-m2repository
- extra-android-m2repository
 
before_script:
- chmod +x scripts/prepare-build.sh
- ./prepare-build.sh
- chmod +x gradlew
 
script: "./gradlew build"
script: "./gradlew build --stacktrace"
Loading
Loading
@@ -11,22 +11,31 @@ Please see the [issues](https://gitlab.com/Commit451/GitLabAndroid/issues) secti
report any bugs or feature requests and to see the list of known issues.
 
## Libraries
The following 3rd party libraries are the reason this app works. Rapid development is easily attainable thanks to these fine folks and the work they do:
The following 3rd party libraries and resources are the reason this app works. Rapid development is easily attainable thanks to these fine folks and the work they do:
 
- AppCompat (https://developer.android.com/tools/support-library/features.html)
- Design (https://developer.android.com/tools/support-library/features.html)
- RecyclerView (https://developer.android.com/tools/support-library/features.html)
- CardView (https://developer.android.com/tools/support-library/features.html)
- Palette (https://developer.android.com/tools/support-library/features.html)
- Picasso (http://square.github.io/picasso/)
- Retrofit (http://square.github.io/retrofit/)
- OkHttp (http://square.github.io/okhttp/)
- Picasso (http://square.github.io/picasso/)
- Otto (http://square.github.io/otto/)
- Butter Knife (http://jakewharton.github.io/butterknife/)
- Timber (https://github.com/JakeWharton/timber)
- GSON (https://github.com/google/gson)
- Joda Time Android (https://github.com/dlew/joda-time-android)
- Parceler (https://github.com/johncarl81/parceler)
- Bypass (https://github.com/Uncodin/bypass)
- Bypasses (https://github.com/Commit451/bypasses)
- Easel (https://github.com/Commit451/Easel)
- CircleImageView (https://github.com/hdodenhof/CircleImageView)
- Material-ish Progress (https://github.com/pnikosis/materialish-progress)
- PhysicsLayout (https://github.com/Jawnnypoo/PhysicsLayout)
- CircleImageView (https://github.com/hdodenhof/CircleImageView)
- Material Letter Icon (https://github.com/IvBaranov/MaterialLetterIcon)
- RobotoTextView (https://github.com/johnkil/Android-RobotoTextView)
- GitDiffTextView (https://github.com/alorma/GitDiffTextView)
- MaterialDateTimePicker (https://github.com/wdullaer/MaterialDateTimePicker)
 
## Contributing
Please fork this repository and contribute back! All Merge Requests should be made against the `develop` branch, as it is the active branch for development. Please make your best effort to break up commits as much as possible to improve the reviewing process.
Loading
Loading
Loading
Loading
@@ -9,12 +9,12 @@ android {
applicationId "com.commit451.gitlab"
minSdkVersion 16
targetSdkVersion 23
versionCode 214
versionName "2.1.4"
versionCode 220
versionName "2.2.0"
}
buildTypes {
release {
minifyEnabled false
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
Loading
Loading
@@ -34,8 +34,6 @@ dependencies {
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:cardview-v7:23.1.1'
compile 'com.android.support:palette-v7:23.1.1'
compile 'com.google.code.gson:gson:2.4'
compile 'net.danlew:android.joda:2.9.0'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
Loading
Loading
@@ -44,17 +42,21 @@ dependencies {
exclude group: 'stax', module: 'stax-api'
exclude group: 'stax', module: 'stax'
}
compile 'com.squareup.okhttp:okhttp:2.6.0'
compile 'com.squareup.okhttp:okhttp:2.7.2'
compile 'com.squareup:otto:1.3.8'
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.jakewharton.timber:timber:4.1.0'
compile 'de.hdodenhof:circleimageview:2.0.0'
compile 'com.pnikosis:materialish-progress:1.7'
compile 'com.google.code.gson:gson:2.5'
compile 'net.danlew:android.joda:2.9.1'
compile "org.parceler:parceler-api:1.0.3"
apt "org.parceler:parceler:1.0.3"
compile 'com.jawnnypoo:physicslayout:1.0.0'
compile 'com.commit451:bypasses:1.0.1'
compile 'com.commit451:easel:0.0.4'
compile 'de.hdodenhof:circleimageview:2.0.0'
compile 'com.pnikosis:materialish-progress:1.7'
compile 'com.jawnnypoo:physicslayout:1.0.1'
compile 'com.github.ivbaranov:MaterialLetterIcon:0.2.1'
compile 'com.github.johnkil.android-robototextview:robototextview:2.4.3'
compile 'com.github.alorma:diff-textview:1.1.0'
compile 'com.wdullaer:materialdatetimepicker:2.1.1'
}
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:/Program Files/Android-Studio/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Just want proguard to strip unused things, don't care about people
# seeing the source
-dontobfuscate
# So that Fabric can still have line numbers
-keepattributes SourceFile,LineNumberTable
# Picasso rules
-dontwarn com.squareup.okhttp.**
# Retrofit rules
-keep class com.squareup.okhttp.** { *; }
-keep class retrofit.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-dontwarn com.squareup.okhttp.**
-dontwarn okio.**
-dontwarn retrofit.**
-dontwarn rx.**
-keepclasseswithmembers class * {
@retrofit.http.* <methods>;
}
# If in your rest service interface you use methods with Callback argument.
-keepattributes Exceptions
# If your rest service methods throw custom exceptions, because you've defined an ErrorHandler.
-keepattributes Signature
# Also you must note that if you are using GSON for conversion from JSON to POJO representation, you must ignore those POJO classes from being obfuscated.
# Here include the POJO's that have you have created for mapping JSON response to POJO for example.
## GSON 2.2.4 specific rules ##
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
-keepattributes EnclosingMethod
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.commit451.gitlab.model.** { *; }
# Simple-Xml Proguard Config
# Keep public classes and methods.
-dontwarn com.bea.xml.stream.**
-keep class org.simpleframework.xml.**{ *; }
-keepclassmembers,allowobfuscation class * {
@org.simpleframework.xml.* <fields>;
@org.simpleframework.xml.* <init>(...);
}
-dontwarn javax.xml.stream.events.**
-dontwarn javax.xml.**
# OkHttp
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-dontwarn com.squareup.okhttp.**
## Square Otto specific rules ##
## https://square.github.io/otto/ ##
-keepclassmembers class ** {
@com.squareup.otto.Subscribe public *;
@com.squareup.otto.Produce public *;
}
# ButterKnife 7
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
## joda-time-android 2.8.0
# This is only necessary if you are not including the optional joda-convert dependency
-dontwarn org.joda.convert.FromString
-dontwarn org.joda.convert.ToString
# Parcel library
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keep class org.parceler.Parceler$$Parcels
# Unicoding Bypass library
-keep class in.uncod.android.** { *; }
\ No newline at end of file
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:/Program Files/Android-Studio/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
-dontwarn com.squareup.okhttp.**
-keep class retrofit.** { *; }
-dontwarn retrofit.**
-dontwarn butterknife.internal.**
-keep class **$$ViewInjector { *; }
-keepnames class * { @butterknife.InjectView *;}
\ No newline at end of file
Loading
Loading
@@ -10,12 +10,13 @@
<application
android:name="com.commit451.gitlab.GitLabApp"
android:allowBackup="true"
android:fullBackupContent="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
 
<activity
android:name=".activities.GitlabActivity"
android:name=".activity.GitlabActivity"
android:theme="@android:style/Theme.NoDisplay"
android:noHistory="true" >
<intent-filter>
Loading
Loading
@@ -24,38 +25,39 @@
</intent-filter>
</activity>
 
<activity android:name=".activities.ProjectActivity" />
<activity android:name=".activity.ProjectActivity" />
 
<activity android:name=".activities.LoginActivity" />
<activity android:name=".activity.LoginActivity" />
 
<activity android:name=".activities.ProjectsActivity"
android:theme="@style/Activity.Projects"/>
<activity android:name=".activity.ProjectsActivity"
android:theme="@style/Activity.Projects"
android:launchMode="singleTask"/>
 
<activity android:name=".activities.GroupsActivity"
android:theme="@style/Activity.Groups"/>
<activity android:name=".activity.GroupsActivity"
android:theme="@style/Activity.Groups"
android:launchMode="singleTask"/>
 
<activity
android:name=".activities.FileActivity"
android:configChanges="orientation|screenSize" >
android:name=".activity.FileActivity">
</activity>
<activity
android:name=".activities.IssueActivity"
android:configChanges="orientation|screenSize" >
android:name=".activity.IssueActivity" >
</activity>
<activity
android:name=".activities.DiffActivity"
android:configChanges="orientation|screenSize" >
android:name=".activity.DiffActivity" >
</activity>
 
<activity android:name=".activities.AboutActivity"/>
<activity android:name=".activities.AddUserActivity"/>
<activity android:name=".activities.UserActivity"
<activity android:name=".activity.AboutActivity"/>
<activity android:name=".activity.AddUserActivity"/>
<activity android:name=".activity.UserActivity"
android:theme="@style/Activity.User"/>
<activity android:name=".activities.SearchActivity"/>
<activity android:name=".activities.GroupActivity"
<activity android:name=".activity.SearchActivity"/>
<activity android:name=".activity.GroupActivity"
android:theme="@style/Activity.Group"/>
<activity android:name=".activities.MergeRequestActivity"/>
<activity android:name=".dialogs.NewIssuePopupDialog" android:theme="@style/Activity.Translucent"/>
<activity android:name=".activity.MergeRequestActivity"/>
<activity android:name=".activity.AddIssueActivity"/>
<activity android:name=".activity.MilestoneActivity"/>
<activity android:name=".activity.AddMilestoneActivity"/>
</application>
 
</manifest>
\ No newline at end of file
package com.commit451.gitlab;
 
import android.app.Application;
import android.content.res.Configuration;
import android.content.res.Resources;
 
import com.squareup.otto.Bus;
 
import net.danlew.android.joda.JodaTimeAndroid;
 
import java.util.Locale;
import timber.log.Timber;
 
/**
* App for one time init things
* Created by Jawn on 7/27/2015.
* App for one time init things and to house singletons
*/
public class GitLabApp extends Application {
 
private static Bus bus;
private static Bus sBus;
public static Bus bus() {
if (bus == null) {
bus = new Bus();
if (sBus == null) {
sBus = new Bus();
}
return bus;
return sBus;
}
 
private static GitLabApp instance;
private static GitLabApp sInstance;
public static GitLabApp instance() {
return instance;
return sInstance;
}
 
@Override
public void onCreate() {
super.onCreate();
instance = this;
sInstance = this;
forceLocale(Locale.ENGLISH);
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
}
JodaTimeAndroid.init(this);
}
private void forceLocale(Locale locale){
try {
Locale.setDefault(locale);
Resources[] resources = new Resources[]{
Resources.getSystem(),
getBaseContext().getResources()
};
for (Resources res : resources) {
Configuration configuration = res.getConfiguration();
configuration.locale = locale;
res.updateConfiguration(configuration, res.getDisplayMetrics());
}
} catch (Exception e) {
Timber.e(e, null);
}
}
}
package com.commit451.gitlab.activities;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import com.commit451.gitlab.R;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.model.Diff;
import com.commit451.gitlab.model.DiffLine;
import com.commit451.gitlab.model.Project;
import com.commit451.gitlab.views.DiffView;
import com.commit451.gitlab.views.MessageView;
import org.parceler.Parcels;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
import timber.log.Timber;
public class DiffActivity extends BaseActivity {
private static final String EXTRA_PROJECT = "extra_project";
private static final String EXTRA_COMMIT = "extra_commit";
public static Intent newInstance(Context context, Project project, DiffLine commit) {
Intent intent = new Intent(context, DiffActivity.class);
intent.putExtra(EXTRA_PROJECT, Parcels.wrap(project));
intent.putExtra(EXTRA_COMMIT, Parcels.wrap(commit));
return intent;
}
@Bind(R.id.toolbar) Toolbar toolbar;
@Bind(R.id.message_container) LinearLayout messageContainer;
@Bind(R.id.diff_container) LinearLayout diffContainer;
Project mProject;
DiffLine mCommit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diff);
ButterKnife.bind(this);
mProject = Parcels.unwrap(getIntent().getParcelableExtra(EXTRA_PROJECT));
mCommit = Parcels.unwrap(getIntent().getParcelableExtra(EXTRA_COMMIT));
toolbar.setNavigationIcon(R.drawable.ic_back_24dp);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
toolbar.setTitle(mCommit.getShortId());
toolbar.inflateMenu(R.menu.diff);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.text_wrap_checkbox:
item.setChecked(!item.isChecked());
setTextWrap(item.isChecked());
return true;
}
return false;
}
});
//TODO make this use RecyclerViews, cause this is insane
GitLabClient.instance().getCommit(mProject.getId(), mCommit.getId()).enqueue(commitCallback);
GitLabClient.instance().getCommitDiff(mProject.getId(), mCommit.getId()).enqueue(diffCallback);
}
private Callback<DiffLine> commitCallback = new Callback<DiffLine>() {
@Override
public void onResponse(Response<DiffLine> response, Retrofit retrofit) {
if (response.isSuccess()) {
messageContainer.addView(new MessageView(DiffActivity.this, response.body()));
}
}
@Override
public void onFailure(Throwable t) {
Timber.e(t.toString());
Snackbar.make(getWindow().getDecorView(), getString(R.string.connection_error), Snackbar.LENGTH_SHORT)
.show();
}
};
private Callback<List<Diff>> diffCallback = new Callback<List<Diff>>() {
@Override
public void onResponse(Response<List<Diff>> response, Retrofit retrofit) {
if (response.isSuccess()) {
for(Diff diff : response.body()) {
diffContainer.addView(new DiffView(DiffActivity.this, diff));
}
}
}
@Override
public void onFailure(Throwable t) {
Timber.e(t.toString());
Snackbar.make(getWindow().getDecorView(), getString(R.string.connection_error), Snackbar.LENGTH_SHORT)
.show();
}
};
private void setTextWrap(boolean checked) {
((MessageView) messageContainer.getChildAt(0)).setWrapped(checked);
for(int i = 0; i < diffContainer.getChildCount(); ++i) {
((DiffView) diffContainer.getChildAt(i)).setWrapped(checked);
}
}
}
\ No newline at end of file
package com.commit451.gitlab.activities;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.util.Base64;
import android.view.MenuItem;
import android.view.View;
import android.webkit.MimeTypeMap;
import android.webkit.WebView;
import com.commit451.gitlab.R;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.model.FileResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import butterknife.Bind;
import butterknife.ButterKnife;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
import timber.log.Timber;
public class FileActivity extends BaseActivity {
private static final String EXTRA_PROJECT_ID = "extra_project_id";
private static final String EXTRA_PATH = "extra_path";
private static final String EXTRA_REF = "extra_ref";
public static Intent newIntent(Context context, long projectId, String path, String ref) {
Intent intent = new Intent(context, FileActivity.class);
intent.putExtra(EXTRA_PROJECT_ID, projectId);
intent.putExtra(EXTRA_PATH, path);
intent.putExtra(EXTRA_REF, ref);
return intent;
}
@Bind(R.id.toolbar) Toolbar toolbar;
@Bind(R.id.file_blob) WebView fileBlobView;
@Bind(R.id.progress) View progress;
long mProjectId;
String mPath;
String mRef;
String mFileName;
byte[] mBlob;
private final Callback<FileResponse> mFileResponseCallback = new Callback<FileResponse>() {
@Override
public void onResponse(Response<FileResponse> response, Retrofit retrofit) {
if (!response.isSuccess()) {
return;
}
progress.setVisibility(View.GONE);
String text = getString(R.string.file_load_error);
// Receiving side
mFileName = response.body().getFileName();
mBlob = Base64.decode(response.body().getContent(), Base64.DEFAULT);
String content;
String mimeType = null;
String ext = fileExt(mFileName);
if (ext != null) {
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext.substring(1));
}
if (mimeType != null && mimeType.startsWith("image/")) {
String imageURL = "data:" + mimeType + ";base64," + response.body().getContent();
content = "<!DOCTYPE html><html><head><link href=\"github.css\" rel=\"stylesheet\" /></head><body><img style=\"width: 100%;\" src=\"" + imageURL + "\"></body></html>";
}
else {
try {
text = new String(mBlob, "UTF-8");
}
catch (UnsupportedEncodingException e) {
Timber.e(e.toString());
}
content = "<!DOCTYPE html><html><head><link href=\"github.css\" rel=\"stylesheet\" /></head><body><pre><code>" + Html.escapeHtml(text) + "</code></pre><script src=\"highlight.pack.js\"></script><script>hljs.initHighlightingOnLoad();</script></body></html>";
}
fileBlobView.loadDataWithBaseURL("file:///android_asset/", content, "text/html", "utf8", null);
toolbar.setTitle(mFileName);
toolbar.inflateMenu(R.menu.file);
}
@Override
public void onFailure(Throwable t) {
progress.setVisibility(View.GONE);
Snackbar.make(getWindow().getDecorView(), R.string.file_load_error, Snackbar.LENGTH_SHORT)
.show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file);
ButterKnife.bind(this);
mProjectId = getIntent().getLongExtra(EXTRA_PROJECT_ID, -1);
mPath = getIntent().getStringExtra(EXTRA_PATH);
mRef = getIntent().getStringExtra(EXTRA_REF);
setupUI();
load();
}
private void load() {
progress.setVisibility(View.VISIBLE);
GitLabClient.instance().getFile(mProjectId, mPath, mRef).enqueue(mFileResponseCallback);
}
private void setupUI() {
toolbar.setNavigationIcon(R.drawable.ic_back_24dp);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch(item.getItemId()) {
case R.id.action_open:
openFile();
return true;
case R.id.action_save:
saveBlob();
return true;
}
return false;
}
});
}
private File saveBlob() {
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state) && mBlob != null) {
File downloadFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File newFile = new File(downloadFolder, mFileName);
try {
FileOutputStream f = new FileOutputStream(newFile);
f.write(mBlob);
f.close();
Snackbar.make(getWindow().getDecorView(), getString(R.string.file_saved), Snackbar.LENGTH_SHORT)
.show();
return newFile;
}
catch(IOException e) {
Snackbar.make(getWindow().getDecorView(), getString(R.string.save_error), Snackbar.LENGTH_SHORT)
.show();
}
}
else {
Snackbar.make(getWindow().getDecorView(), getString(R.string.save_error), Snackbar.LENGTH_SHORT)
.show();
}
return null;
}
private void openFile() {
File file = saveBlob();
if(file == null) {
Snackbar.make(getWindow().getDecorView(), getString(R.string.open_error), Snackbar.LENGTH_SHORT)
.show();
return;
}
MimeTypeMap myMime = MimeTypeMap.getSingleton();
Intent newIntent = new Intent(Intent.ACTION_VIEW);
String fileExt = fileExt(file.toString());
if (fileExt == null) {
Snackbar.make(getWindow().getDecorView(), getString(R.string.open_error), Snackbar.LENGTH_SHORT)
.show();
return;
}
String mimeType = myMime.getMimeTypeFromExtension(fileExt.substring(1));
newIntent.setDataAndType(Uri.fromFile(file), mimeType);
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(newIntent);
}
catch(android.content.ActivityNotFoundException e) {
Snackbar.make(getWindow().getDecorView(), getString(R.string.open_error), Snackbar.LENGTH_SHORT)
.show();
}
}
private String fileExt(String url) {
if(url.contains("?")) {
url = url.substring(0, url.indexOf("?"));
}
if(!url.contains(".")) {
return null;
}
else {
String ext = url.substring(url.lastIndexOf("."));
if(ext.contains("%")) {
ext = ext.substring(0, ext.indexOf("%"));
}
if(ext.contains("/")) {
ext = ext.substring(0, ext.indexOf("/"));
}
return ext.toLowerCase();
}
}
}
package com.commit451.gitlab.activities;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import com.commit451.gitlab.GitLabApp;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.SectionsPagerAdapter;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.events.ProjectReloadEvent;
import com.commit451.gitlab.fragments.CommitsFragment;
import com.commit451.gitlab.fragments.FilesFragment;
import com.commit451.gitlab.fragments.IssuesFragment;
import com.commit451.gitlab.fragments.MergeRequestsFragment;
import com.commit451.gitlab.fragments.MembersFragment;
import com.commit451.gitlab.fragments.OverviewFragment;
import com.commit451.gitlab.model.Branch;
import com.commit451.gitlab.model.Project;
import com.commit451.gitlab.tools.IntentUtil;
import org.parceler.Parcels;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
import timber.log.Timber;
public class ProjectActivity extends BaseActivity {
private static final String EXTRA_PROJECT = "extra_project";
public static Intent newInstance(Context context, Project project) {
Intent intent = new Intent(context, ProjectActivity.class);
intent.putExtra(EXTRA_PROJECT, Parcels.wrap(project));
return intent;
}
@Bind(R.id.toolbar) Toolbar mToolbar;
@Bind(R.id.tabs) TabLayout mTabLayout;
@Bind(R.id.branch_spinner) Spinner mBranchSpinner;
@Bind(R.id.progress) View mProgress;
@Bind(R.id.pager) ViewPager mViewPager;
private final AdapterView.OnItemSelectedListener mSpinnerItemSelectedListener = new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mBranchName = ((TextView)view).getText().toString();
broadcastLoad();
}
@Override
public void onNothingSelected(AdapterView<?> parent) { }
};
Project mProject;
String mBranchName;
private Callback<List<Branch>> mBranchesCallback = new Callback<List<Branch>>() {
@Override
public void onResponse(Response<List<Branch>> response, Retrofit retrofit) {
if (!response.isSuccess()) {
return;
}
mProgress.setVisibility(View.GONE);
if(response.body().isEmpty()) {
mBranchSpinner.setVisibility(View.GONE);
} else {
mBranchSpinner.setVisibility(View.VISIBLE);
mBranchSpinner.setAlpha(0.0f);
mBranchSpinner.animate().alpha(1.0f);
// Set up the dropdown list navigation in the action bar.
mBranchSpinner.setAdapter(new ArrayAdapter<>(ProjectActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1, response.body()));
}
for (int i=0; i<response.body().size(); i++) {
if (response.body().get(i).getName().equals(mProject.getDefaultBranch())) {
mBranchSpinner.setSelection(i);
}
}
mBranchSpinner.setOnItemSelectedListener(mSpinnerItemSelectedListener);
if(response.body().isEmpty()) {
broadcastLoad();
}
}
@Override
public void onFailure(Throwable t) {
mProgress.setVisibility(View.GONE);
Timber.e(t.toString());
Snackbar.make(getWindow().getDecorView(), getString(R.string.connection_error), Snackbar.LENGTH_SHORT)
.show();
}
};
private final Toolbar.OnMenuItemClickListener mOnMenuItemClickListener = new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_share:
IntentUtil.share(getWindow().getDecorView(), mProject.getWebUrl());
return true;
}
return false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_project);
ButterKnife.bind(this);
mProject = Parcels.unwrap(getIntent().getParcelableExtra(EXTRA_PROJECT));
mToolbar.setNavigationIcon(R.drawable.ic_back_24dp);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
mToolbar.inflateMenu(R.menu.menu_repository);
mToolbar.setOnMenuItemClickListener(mOnMenuItemClickListener);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
mViewPager.setAdapter(sectionsPagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
loadBranches();
}
private void loadBranches() {
GitLabClient.instance().getBranches(mProject.getId()).enqueue(mBranchesCallback);
}
private void broadcastLoad() {
GitLabApp.bus().post(new ProjectReloadEvent(mProject, mBranchName));
}
@Override
public void onBackPressed() {
boolean handled = false;
switch(mViewPager.getCurrentItem()) {
case 0:
OverviewFragment overviewFragment = (OverviewFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":0");
handled = overviewFragment.onBackPressed();
break;
case 1:
CommitsFragment commitsFragment = (CommitsFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":1");
handled = commitsFragment.onBackPressed();
break;
case 2:
IssuesFragment issuesFragment = (IssuesFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":2");
handled = issuesFragment.onBackPressed();
break;
case 3:
FilesFragment filesFragment = (FilesFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":3");
handled = filesFragment.onBackPressed();
break;
case 4:
MergeRequestsFragment mergeRequestsFragment = (MergeRequestsFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":4");
handled = mergeRequestsFragment.onBackPressed();
break;
case 5:
MembersFragment membersFragment = (MembersFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":5");
handled = membersFragment.onBackPressed();
break;
}
if(!handled) {
super.onBackPressed();
}
}
public String getBranchName() {
return mBranchName;
}
public Project getProject() {
return mProject;
}
}
package com.commit451.gitlab.activities;
package com.commit451.gitlab.activity;
 
import android.content.Context;
import android.content.Intent;
Loading
Loading
@@ -7,6 +7,7 @@ import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.Toolbar;
Loading
Loading
@@ -16,14 +17,13 @@ import android.widget.TextView;
 
import com.commit451.gitlab.R;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.model.Contributor;
import com.commit451.gitlab.tools.ImageUtil;
import com.commit451.gitlab.tools.IntentUtil;
import com.commit451.gitlab.tools.WindowUtil;
import com.commit451.gitlab.model.api.Contributor;
import com.commit451.gitlab.util.ImageUtil;
import com.commit451.gitlab.util.IntentUtil;
import com.commit451.gitlab.util.WindowUtil;
import com.jawnnypoo.physicslayout.Physics;
import com.jawnnypoo.physicslayout.PhysicsConfig;
import com.jawnnypoo.physicslayout.PhysicsFrameLayout;
import com.squareup.picasso.Picasso;
 
import org.jbox2d.common.Vec2;
 
Loading
Loading
@@ -57,7 +57,7 @@ public class AboutActivity extends BaseActivity {
@Bind(R.id.physics_layout) PhysicsFrameLayout physicsLayout;
@OnClick(R.id.sauce)
void onSauceClick() {
IntentUtil.openPage(root, getString(R.string.source_url));
IntentUtil.openPage(root, Uri.parse(getString(R.string.source_url)));
}
 
SensorManager sensorManager;
Loading
Loading
@@ -84,14 +84,14 @@ public class AboutActivity extends BaseActivity {
if (!response.isSuccess()) {
return;
}
addContributors(response.body());
addContributors(Contributor.groupContributors(response.body()));
}
 
@Override
public void onFailure(Throwable t) {
Timber.e(t, null);
Snackbar.make(getWindow().getDecorView(), R.string.failed_to_load_contributors, Snackbar.LENGTH_SHORT)
.show();
Timber.e(t.toString());
}
};
 
Loading
Loading
@@ -157,8 +157,9 @@ public class AboutActivity extends BaseActivity {
x = 0;
y = (y + imageSize) % physicsLayout.getHeight();
}
String url = ImageUtil.getGravatarUrl(contributor.getEmail(), imageSize);
Picasso.with(this)
Uri url = ImageUtil.getAvatarUrl(contributor.getEmail(), imageSize);
GitLabClient.getPicasso()
.load(url)
.into(imageView);
}
Loading
Loading
package com.commit451.gitlab.activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.TextInputLayout;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import com.commit451.gitlab.GitLabApp;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.AssigneeSpinnerAdapter;
import com.commit451.gitlab.adapter.MilestoneSpinnerAdapter;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.event.IssueChangedEvent;
import com.commit451.gitlab.event.IssueCreatedEvent;
import com.commit451.gitlab.model.api.Issue;
import com.commit451.gitlab.model.api.Member;
import com.commit451.gitlab.model.api.Milestone;
import com.commit451.gitlab.model.api.Project;
import org.parceler.Parcels;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
import timber.log.Timber;
/**
* Activity to input new issues, but not really a dialog at all wink wink
*/
public class AddIssueActivity extends MorphActivity {
private static final String KEY_PROJECT = "project";
private static final String KEY_ISSUE = "issue";
public static Intent newIntent(Context context, Project project, Issue issue) {
Intent intent = new Intent(context, AddIssueActivity.class);
intent.putExtra(KEY_PROJECT, Parcels.wrap(project));
if (issue != null) {
intent.putExtra(KEY_ISSUE, Parcels.wrap(issue));
}
return intent;
}
@Bind(R.id.root) ViewGroup mRoot;
@Bind(R.id.toolbar) Toolbar mToolbar;
@Bind(R.id.title_text_input_layout) TextInputLayout mTitleInputLayout;
@Bind(R.id.title) EditText mTitleInput;
@Bind(R.id.description) EditText mDescriptionInput;
@Bind(R.id.progress) View mProgress;
@Bind(R.id.assignee_progress) View mAssigneeProgress;
@Bind(R.id.assignee_spinner) Spinner mAssigneeSpinner;
@Bind(R.id.milestone_progress) View mMilestoneProgress;
@Bind(R.id.milestone_spinner) Spinner mMilestoneSpinner;
private Project mProject;
private Issue mIssue;
private HashSet<Member> mMembers;
private final Callback<List<Milestone>> mMilestonesCallback = new Callback<List<Milestone>>() {
@Override
public void onResponse(Response<List<Milestone>> response, Retrofit retrofit) {
mMilestoneProgress.setVisibility(View.GONE);
if (!response.isSuccess()) {
mMilestoneSpinner.setVisibility(View.GONE);
return;
}
mMilestoneSpinner.setVisibility(View.VISIBLE);
MilestoneSpinnerAdapter milestoneSpinnerAdapter = new MilestoneSpinnerAdapter(AddIssueActivity.this, response.body());
mMilestoneSpinner.setAdapter(milestoneSpinnerAdapter);
if (mIssue != null) {
mMilestoneSpinner.setSelection(milestoneSpinnerAdapter.getSelectedItemPosition(mIssue.getMilestone()));
}
}
@Override
public void onFailure(Throwable t) {
Timber.e(t, null);
mMilestoneProgress.setVisibility(View.GONE);
mMilestoneSpinner.setVisibility(View.GONE);
}
};
private final Callback<List<Member>> mAssigneeCallback = new Callback<List<Member>>() {
@Override
public void onResponse(Response<List<Member>> response, Retrofit retrofit) {
if (!response.isSuccess()) {
mAssigneeProgress.setVisibility(View.GONE);
mAssigneeSpinner.setVisibility(View.GONE);
return;
}
if (response.body() != null) {
mMembers.addAll(response.body());
}
if (mProject.belongsToGroup()) {
Timber.d("Project belongs to a group, loading those users too");
GitLabClient.instance().getGroupMembers(mProject.getNamespace().getId()).enqueue(mGroupMembersCallback);
} else {
setAssignees();
}
}
@Override
public void onFailure(Throwable t) {
Timber.e(t, null);
mAssigneeSpinner.setVisibility(View.GONE);
mAssigneeProgress.setVisibility(View.GONE);
}
};
private final Callback<List<Member>> mGroupMembersCallback = new Callback<List<Member>>() {
@Override
public void onResponse(Response<List<Member>> response, Retrofit retrofit) {
if (!response.isSuccess()) {
mAssigneeSpinner.setVisibility(View.GONE);
return;
}
if (response.body() != null) {
mMembers.addAll(response.body());
}
setAssignees();
}
@Override
public void onFailure(Throwable t) {
Timber.e(t, null);
mAssigneeSpinner.setVisibility(View.GONE);
mAssigneeProgress.setVisibility(View.GONE);
}
};
private final Callback<Issue> mIssueCreatedCallback = new Callback<Issue>() {
@Override
public void onResponse(Response<Issue> response, Retrofit retrofit) {
if (!response.isSuccess()) {
Toast.makeText(AddIssueActivity.this, getString(R.string.failed_to_create_issue), Toast.LENGTH_SHORT)
.show();
return;
}
if (mIssue == null) {
GitLabApp.bus().post(new IssueCreatedEvent(response.body()));
} else {
GitLabApp.bus().post(new IssueChangedEvent(response.body()));
}
dismiss();
}
@Override
public void onFailure(Throwable t) {
Timber.e(t, null);
Toast.makeText(AddIssueActivity.this, getString(R.string.connection_error), Toast.LENGTH_SHORT)
.show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_issue);
ButterKnife.bind(this);
morph(mRoot);
mProject = Parcels.unwrap(getIntent().getParcelableExtra(KEY_PROJECT));
mIssue = Parcels.unwrap(getIntent().getParcelableExtra(KEY_ISSUE));
mMembers = new HashSet<>();
mToolbar.setNavigationIcon(R.drawable.ic_back_24dp);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_create:
case R.id.action_edit:
save();
return true;
}
return false;
}
});
if (mIssue != null) {
bindIssue();
mToolbar.inflateMenu(R.menu.menu_edit_milestone);
} else {
mToolbar.inflateMenu(R.menu.menu_add_milestone);
}
load();
}
private void load() {
GitLabClient.instance().getMilestones(mProject.getId()).enqueue(mMilestonesCallback);
GitLabClient.instance().getProjectMembers(mProject.getId()).enqueue(mAssigneeCallback);
}
private void showLoading() {
mProgress.setVisibility(View.VISIBLE);
mProgress.setAlpha(0.0f);
mProgress.animate().alpha(1.0f);
}
private void bindIssue() {
if (!TextUtils.isEmpty(mIssue.getTitle())) {
mTitleInput.setText(mIssue.getTitle());
}
if (!TextUtils.isEmpty(mIssue.getDescription())) {
mDescriptionInput.setText(mIssue.getDescription());
}
}
private void setAssignees() {
mAssigneeProgress.setVisibility(View.GONE);
mAssigneeSpinner.setVisibility(View.VISIBLE);
AssigneeSpinnerAdapter assigneeSpinnerAdapter = new AssigneeSpinnerAdapter(this, new ArrayList<>(mMembers));
mAssigneeSpinner.setAdapter(assigneeSpinnerAdapter);
if (mIssue != null) {
mAssigneeSpinner.setSelection(assigneeSpinnerAdapter.getSelectedItemPosition(mIssue.getAssignee()));
}
}
private void save() {
if(!TextUtils.isEmpty(mTitleInput.getText())) {
mTitleInputLayout.setError(null);
showLoading();
Long assigneeId = null;
if (mAssigneeSpinner.getAdapter() != null ) {
//the user did make a selection of some sort. So update it
Member member = (Member) mAssigneeSpinner.getSelectedItem();
if (member == null) {
//Removes the assignment
assigneeId = 0L;
} else {
assigneeId = member.getId();
}
}
Long milestoneId = null;
if (mMilestoneSpinner.getAdapter() != null) {
//the user did make a selection of some sort. So update it
Milestone milestone = (Milestone) mMilestoneSpinner.getSelectedItem();
if (milestone == null) {
//Removes the assignment
milestoneId = 0L;
} else {
milestoneId = milestone.getId();
}
}
createOrSaveIssue(mTitleInput.getText().toString(),
mDescriptionInput.getText().toString(),
assigneeId,
milestoneId);
}
else {
mTitleInputLayout.setError(getString(R.string.required_field));
}
}
private void createOrSaveIssue(String title, String description, Long assigneeId, Long milestoneId) {
if (mIssue == null) {
GitLabClient.instance().createIssue(
mProject.getId(),
title,
description,
assigneeId,
milestoneId).enqueue(mIssueCreatedCallback);
} else {
GitLabClient.instance().updateIssue(mProject.getId(),
mIssue.getId(),
title,
description,
assigneeId,
milestoneId).enqueue(mIssueCreatedCallback);
}
}
}
\ No newline at end of file
package com.commit451.gitlab.activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputLayout;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.commit451.gitlab.GitLabApp;
import com.commit451.gitlab.R;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.event.MilestoneChangedEvent;
import com.commit451.gitlab.event.MilestoneCreatedEvent;
import com.commit451.gitlab.model.api.Milestone;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import org.parceler.Parcels;
import java.util.Calendar;
import java.util.Date;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
import timber.log.Timber;
public class AddMilestoneActivity extends MorphActivity {
private static final String KEY_PROJECT_ID = "project_id";
private static final String KEY_MILESTONE = "milestone";
public static Intent newInstance(Context context, long projectId) {
return newInstance(context, projectId, null);
}
public static Intent newInstance(Context context, long projectId, Milestone milestone) {
Intent intent = new Intent(context, AddMilestoneActivity.class);
intent.putExtra(KEY_PROJECT_ID, projectId);
if (milestone != null) {
intent.putExtra(KEY_MILESTONE, Parcels.wrap(milestone));
}
return intent;
}
@Bind(R.id.root)
View mRoot;
@Bind(R.id.toolbar)
Toolbar mToolbar;
@Bind(R.id.title_text_input_layout)
TextInputLayout mTitleTextInputLayout;
@Bind(R.id.title)
EditText mTitle;
@Bind(R.id.description)
EditText mDescription;
@Bind(R.id.due_date)
Button mDueDate;
@Bind(R.id.progress)
View mProgress;
@OnClick(R.id.due_date)
void onDueDateClicked() {
Calendar now = Calendar.getInstance();
if (mCurrentDate != null) {
now.setTime(mCurrentDate);
}
DatePickerDialog dpd = DatePickerDialog.newInstance(
mOnDateSetListener,
now.get(Calendar.YEAR),
now.get(Calendar.MONTH),
now.get(Calendar.DAY_OF_MONTH)
);
dpd.show(getFragmentManager(), "date_picker");
}
long mProjectId;
Milestone mMilestone;
Date mCurrentDate;
private final DatePickerDialog.OnDateSetListener mOnDateSetListener = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, monthOfYear);
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
mCurrentDate = calendar.getTime();
bind(mCurrentDate);
}
};
private final View.OnClickListener mOnBackPressed = new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
};
private Callback<Milestone> mMilestoneCallback = new Callback<Milestone>() {
@Override
public void onResponse(Response<Milestone> response, Retrofit retrofit) {
mProgress.setVisibility(View.GONE);
if (!response.isSuccess()) {
showError();
return;
}
if (mMilestone == null) {
GitLabApp.bus().post(new MilestoneCreatedEvent(response.body()));
} else {
GitLabApp.bus().post(new MilestoneChangedEvent(response.body()));
}
finish();
}
@Override
public void onFailure(Throwable t) {
Timber.e(t, null);
mProgress.setVisibility(View.GONE);
showError();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_milestone);
ButterKnife.bind(this);
morph(mRoot);
mProjectId = getIntent().getLongExtra(KEY_PROJECT_ID, -1);
mMilestone = Parcels.unwrap(getIntent().getParcelableExtra(KEY_MILESTONE));
if (mMilestone != null) {
bind(mMilestone);
mToolbar.inflateMenu(R.menu.menu_edit_milestone);
} else {
mToolbar.inflateMenu(R.menu.menu_add_milestone);
}
mToolbar.setNavigationIcon(R.drawable.ic_back_24dp);
mToolbar.setNavigationOnClickListener(mOnBackPressed);
mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_create:
case R.id.action_edit:
createMilestone();
return true;
}
return false;
}
});
}
private void createMilestone() {
if (TextUtils.isEmpty(mTitle.getText())) {
mTitleTextInputLayout.setError(getString(R.string.required_field));
return;
}
mProgress.setVisibility(View.VISIBLE);
String dueDate = null;
if (mCurrentDate != null) {
dueDate = Milestone.DUE_DATE_FORMAT.format(mCurrentDate);
}
if (mMilestone == null) {
GitLabClient.instance().createMilestone(mProjectId,
mTitle.getText().toString(),
mDescription.getText().toString(),
dueDate).enqueue(mMilestoneCallback);
} else {
GitLabClient.instance().editMilestone(mProjectId,
mMilestone.getId(),
mTitle.getText().toString(),
mDescription.getText().toString(),
dueDate).enqueue(mMilestoneCallback);
}
}
private void showError() {
Snackbar.make(mRoot, getString(R.string.failed_to_create_milestone), Snackbar.LENGTH_SHORT)
.show();
}
private void bind(Date date) {
mDueDate.setText(Milestone.DUE_DATE_FORMAT.format(date));
}
private void bind(Milestone milestone) {
mTitle.setText(milestone.getTitle());
if (milestone.getDescription() != null) {
mDescription.setText(milestone.getDescription());
}
if (milestone.getDueDate() != null) {
mCurrentDate = milestone.getDueDate();
bind(mCurrentDate);
}
}
}
package com.commit451.gitlab.activities;
package com.commit451.gitlab.activity;
 
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
Loading
Loading
@@ -17,14 +21,16 @@ import android.widget.Toast;
 
import com.commit451.gitlab.GitLabApp;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.MemberAdapter;
import com.commit451.gitlab.adapter.UsersAdapter;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.dialogs.UserRoleDialog;
import com.commit451.gitlab.events.UserAddedEvent;
import com.commit451.gitlab.model.Group;
import com.commit451.gitlab.model.User;
import com.commit451.gitlab.tools.KeyboardUtil;
import com.commit451.gitlab.viewHolders.MemberViewHolder;
import com.commit451.gitlab.dialog.AccessDialog;
import com.commit451.gitlab.event.MemberAddedEvent;
import com.commit451.gitlab.model.api.Group;
import com.commit451.gitlab.model.api.Member;
import com.commit451.gitlab.model.api.UserBasic;
import com.commit451.gitlab.util.KeyboardUtil;
import com.commit451.gitlab.util.PaginationUtil;
import com.commit451.gitlab.viewHolder.UserViewHolder;
 
import org.parceler.Parcels;
 
Loading
Loading
@@ -32,6 +38,7 @@ import java.util.List;
 
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
Loading
Loading
@@ -39,9 +46,8 @@ import timber.log.Timber;
 
/**
* Add a new user to the repo or to the group, depending on the mode
* Created by Jawn on 9/15/2015.
*/
public class AddUserActivity extends BaseActivity {
public class AddUserActivity extends MorphActivity {
 
private static final String KEY_PROJECT_ID = "project_id";
private static final String KEY_GROUP = "group";
Loading
Loading
@@ -58,15 +64,33 @@ public class AddUserActivity extends BaseActivity {
return intent;
}
 
@Bind(R.id.root) View mRoot;
@Bind(R.id.toolbar) Toolbar mToolbar;
@Bind(R.id.userSearch) EditText mUserSearch;
@Bind(R.id.search) EditText mUserSearch;
@Bind(R.id.swipe_layout) SwipeRefreshLayout mSwipeRefreshLayout;
@Bind(R.id.list) RecyclerView mRecyclerView;
MemberAdapter mAdapter;
UserRoleDialog mUserRoleDialog;
User mSelectedUser;
@Bind(R.id.clear) View mClearView;
LinearLayoutManager mUserLinearLayoutManager;
@OnClick(R.id.clear)
void onClearClick() {
mClearView.animate().alpha(0.0f).withEndAction(new Runnable() {
@Override
public void run() {
mClearView.setVisibility(View.GONE);
mUserSearch.getText().clear();
}
});
}
UsersAdapter mAdapter;
AccessDialog mAccessDialog;
UserBasic mSelectedUser;
long mProjectId;
Group mGroup;
String mSearchQuery;
Uri mNextPageUrl;
boolean mLoading = false;
 
private final View.OnClickListener mOnBackPressed = new View.OnClickListener() {
@Override
Loading
Loading
@@ -75,49 +99,109 @@ public class AddUserActivity extends BaseActivity {
}
};
 
private final RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = mUserLinearLayoutManager.getChildCount();
int totalItemCount = mUserLinearLayoutManager.getItemCount();
int firstVisibleItem = mUserLinearLayoutManager.findFirstVisibleItemPosition();
if (firstVisibleItem + visibleItemCount >= totalItemCount && !mLoading && mNextPageUrl != null) {
loadMore();
}
}
};
private final TextView.OnEditorActionListener mSearchEditorActionListener = new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (!TextUtils.isEmpty(mUserSearch.getText())) {
KeyboardUtil.hideKeyboard(AddUserActivity.this);
mSwipeRefreshLayout.setRefreshing(true);
GitLabClient.instance().searchUsers(mUserSearch.getText().toString()).enqueue(mUserCallback);
mSearchQuery = mUserSearch.getText().toString();
loadData();
}
return true;
}
};
 
private final Callback<List<User>> mUserCallback = new Callback<List<User>>() {
private final TextWatcher mTextWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (TextUtils.isEmpty(s)) {
mClearView.animate().alpha(0.0f).withEndAction(new Runnable() {
@Override
public void run() {
mClearView.setVisibility(View.GONE);
}
});
} else {
mClearView.setVisibility(View.VISIBLE);
mClearView.animate().alpha(1.0f);
}
}
@Override
public void afterTextChanged(Editable s) {}
};
private final Callback<List<UserBasic>> mUserCallback = new Callback<List<UserBasic>>() {
@Override
public void onResponse(Response<List<User>> response, Retrofit retrofit) {
public void onResponse(Response<List<UserBasic>> response, Retrofit retrofit) {
mSwipeRefreshLayout.setRefreshing(false);
mLoading = false;
if (!response.isSuccess()) {
return;
}
mAdapter.setData(response.body());
mNextPageUrl = PaginationUtil.parse(response).getNext();
Timber.d("HAHA Next page url is " + mNextPageUrl);
}
 
@Override
public void onFailure(Throwable t) {
Timber.e(t.toString());
Timber.e(t, null);
mLoading = false;
Snackbar.make(getWindow().getDecorView(), getString(R.string.connection_error_users), Snackbar.LENGTH_SHORT)
.show();
}
};
 
private final MemberAdapter.Listener mUserClickListener = new MemberAdapter.Listener() {
private final Callback<List<UserBasic>> mMoreUsersCallback = new Callback<List<UserBasic>>() {
@Override
public void onUserClicked(User user, MemberViewHolder memberViewHolder) {
public void onResponse(Response<List<UserBasic>> response, Retrofit retrofit) {
mLoading = false;
if (!response.isSuccess()) {
return;
}
mAdapter.addData(response.body());
mNextPageUrl = PaginationUtil.parse(response).getNext();
}
@Override
public void onFailure(Throwable t) {
Timber.e(t, null);
Snackbar.make(getWindow().getDecorView(), getString(R.string.connection_error_users), Snackbar.LENGTH_SHORT)
.show();
}
};
private final UsersAdapter.Listener mUserClickListener = new UsersAdapter.Listener() {
@Override
public void onUserClicked(UserBasic user, UserViewHolder userViewHolder) {
mSelectedUser = user;
mUserRoleDialog.show();
mAccessDialog.show();
}
};
 
private final UserRoleDialog.Listener mUserRoleDialogListener = new UserRoleDialog.Listener() {
private final AccessDialog.OnAccessAppliedListener mOnAccessAppliedListener = new AccessDialog.OnAccessAppliedListener() {
@Override
public void onAccessLevelClicked(String accessLevel) {
public void onAccessApplied(int accessLevel) {
mAccessDialog.showLoading();
if (mGroup == null) {
GitLabClient.instance().addProjectTeamMember(
GitLabClient.instance().addProjectMember(
mProjectId,
mSelectedUser.getId(),
accessLevel).enqueue(mAddGroupMemeberCallback);
Loading
Loading
@@ -129,9 +213,9 @@ public class AddUserActivity extends BaseActivity {
}
};
 
private final Callback<User> mAddGroupMemeberCallback = new Callback<User>() {
private final Callback<Member> mAddGroupMemeberCallback = new Callback<Member>() {
@Override
public void onResponse(Response<User> response, Retrofit retrofit) {
public void onResponse(Response<Member> response, Retrofit retrofit) {
if (!response.isSuccess()) {
//Conflict
if (response.code() == 409) {
Loading
Loading
@@ -140,14 +224,14 @@ public class AddUserActivity extends BaseActivity {
return;
}
Toast.makeText(AddUserActivity.this, R.string.user_added_successfully, Toast.LENGTH_SHORT).show();
mUserRoleDialog.dismiss();
finish();
GitLabApp.bus().post(new UserAddedEvent(response.body()));
mAccessDialog.dismiss();
dismiss();
GitLabApp.bus().post(new MemberAddedEvent(response.body()));
}
 
@Override
public void onFailure(Throwable t) {
Timber.e(t.toString());
Timber.e(t, null);
}
};
 
Loading
Loading
@@ -158,12 +242,30 @@ public class AddUserActivity extends BaseActivity {
ButterKnife.bind(this);
mProjectId = getIntent().getLongExtra(KEY_PROJECT_ID, -1);
mGroup = Parcels.unwrap(getIntent().getParcelableExtra(KEY_GROUP));
mUserRoleDialog = new UserRoleDialog(this, mUserRoleDialogListener);
mAccessDialog = new AccessDialog(this, mOnAccessAppliedListener);
mToolbar.setNavigationIcon(R.drawable.ic_back_24dp);
mToolbar.setNavigationOnClickListener(mOnBackPressed);
mUserSearch.setOnEditorActionListener(mSearchEditorActionListener);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new MemberAdapter(mUserClickListener);
mUserSearch.addTextChangedListener(mTextWatcher);
mUserLinearLayoutManager = new GridLayoutManager(this, 2);
mRecyclerView.setLayoutManager(mUserLinearLayoutManager);
mAdapter = new UsersAdapter(mUserClickListener);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.addOnScrollListener(mOnScrollListener);
morph(mRoot);
}
private void loadData() {
KeyboardUtil.hideKeyboard(AddUserActivity.this);
mSwipeRefreshLayout.setRefreshing(true);
mLoading = true;
GitLabClient.instance().searchUsers(mSearchQuery).enqueue(mUserCallback);
}
private void loadMore() {
mLoading = true;
Timber.d("loadMore " + mNextPageUrl.toString() + " " + mSearchQuery);
GitLabClient.instance().searchUsers(mNextPageUrl.toString(), mSearchQuery).enqueue(mMoreUsersCallback);
}
}
package com.commit451.gitlab.activities;
package com.commit451.gitlab.activity;
 
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
Loading
Loading
package com.commit451.gitlab.activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.TextView;
import com.commit451.gitlab.R;
import com.commit451.gitlab.adapter.DiffAdapter;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.model.api.Diff;
import com.commit451.gitlab.model.api.Project;
import com.commit451.gitlab.model.api.RepositoryCommit;
import org.parceler.Parcels;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
import timber.log.Timber;
/**
* Shows the lines of a commit aka the diff
*/
public class DiffActivity extends BaseActivity {
private static final String EXTRA_PROJECT = "extra_project";
private static final String EXTRA_COMMIT = "extra_commit";
public static Intent newInstance(Context context, Project project, RepositoryCommit commit) {
Intent intent = new Intent(context, DiffActivity.class);
intent.putExtra(EXTRA_PROJECT, Parcels.wrap(project));
intent.putExtra(EXTRA_COMMIT, Parcels.wrap(commit));
return intent;
}
@Bind(R.id.toolbar) Toolbar mToolbar;
@Bind(R.id.swipe_layout) SwipeRefreshLayout mSwipeRefreshLayout;
@Bind(R.id.list) RecyclerView mDiffRecyclerView;
DiffAdapter mDiffAdapter;
@Bind(R.id.message_text) TextView mMessageText;
private Project mProject;
private RepositoryCommit mCommit;
private Callback<List<Diff>> mDiffCallback = new Callback<List<Diff>>() {
@Override
public void onResponse(Response<List<Diff>> response, Retrofit retrofit) {
mSwipeRefreshLayout.setRefreshing(false);
if (!response.isSuccess()) {
return;
}
for (Diff diff : response.body()) {
Timber.d("diff text: "+ diff.getDiff());
}
mDiffAdapter.setData(response.body());
}
@Override
public void onFailure(Throwable t) {
mSwipeRefreshLayout.setRefreshing(false);
Timber.e(t, null);
mMessageText.setText(R.string.connection_error);
mMessageText.setVisibility(View.VISIBLE);
Snackbar.make(getWindow().getDecorView(), getString(R.string.connection_error), Snackbar.LENGTH_SHORT)
.show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diff);
ButterKnife.bind(this);
mProject = Parcels.unwrap(getIntent().getParcelableExtra(EXTRA_PROJECT));
mCommit = Parcels.unwrap(getIntent().getParcelableExtra(EXTRA_COMMIT));
mToolbar.setNavigationIcon(R.drawable.ic_back_24dp);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
mToolbar.setTitle(mCommit.getShortId());
mDiffAdapter = new DiffAdapter(new DiffAdapter.Listener() {
@Override
public void onDiffClicked(Diff diff) {
}
});
mDiffRecyclerView.setAdapter(mDiffAdapter);
mDiffRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
loadData();
}
});
loadData();
}
private void loadData() {
mMessageText.setVisibility(View.GONE);
mSwipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
if (mSwipeRefreshLayout != null) {
mSwipeRefreshLayout.setRefreshing(true);
}
}
});
GitLabClient.instance().getCommitDiff(mProject.getId(), mCommit.getId()).enqueue(mDiffCallback);
}
}
\ No newline at end of file
package com.commit451.gitlab.activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.util.Base64;
import android.view.MenuItem;
import android.view.View;
import android.webkit.MimeTypeMap;
import android.webkit.WebView;
import com.commit451.gitlab.R;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.model.api.RepositoryFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import butterknife.Bind;
import butterknife.ButterKnife;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
import timber.log.Timber;
public class FileActivity extends BaseActivity {
private static final long MAX_FILE_SIZE = 1024 * 1024;
private static final String EXTRA_PROJECT_ID = "extra_project_id";
private static final String EXTRA_PATH = "extra_path";
private static final String EXTRA_REF = "extra_ref";
public static Intent newIntent(Context context, long projectId, String path, String ref) {
Intent intent = new Intent(context, FileActivity.class);
intent.putExtra(EXTRA_PROJECT_ID, projectId);
intent.putExtra(EXTRA_PATH, path);
intent.putExtra(EXTRA_REF, ref);
return intent;
}
@Bind(R.id.toolbar) Toolbar mToolbar;
@Bind(R.id.file_blob) WebView mFileBlobView;
@Bind(R.id.progress) View mProgressView;
private long mProjectId;
private String mPath;
private String mRef;
private String mFileName;
private byte[] mBlob;
private final Callback<RepositoryFile> mFileResponseCallback = new Callback<RepositoryFile>() {
@Override
public void onResponse(Response<RepositoryFile> response, Retrofit retrofit) {
mProgressView.setVisibility(View.GONE);
if (!response.isSuccess()) {
Snackbar.make(getWindow().getDecorView(), R.string.file_load_error, Snackbar.LENGTH_SHORT)
.show();
return;
}
if (response.body().getSize() > MAX_FILE_SIZE) {
Snackbar.make(getWindow().getDecorView(), R.string.file_too_big, Snackbar.LENGTH_SHORT)
.show();
return;
}
// Receiving side
mFileName = response.body().getFileName();
mBlob = Base64.decode(response.body().getContent(), Base64.DEFAULT);
String content;
String mimeType = null;
String extension = fileExt(mFileName);
if (extension != null) {
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
if (mimeType != null) {
mimeType = mimeType.toLowerCase();
}
}
if (mimeType != null && mimeType.startsWith("image/")) {
String imageURL = "data:" + mimeType + ";base64," + response.body().getContent();
content = "<!DOCTYPE html><html><head><link href=\"github.css\" rel=\"stylesheet\" /></head><body><img style=\"width: 100%;\" src=\"" + imageURL + "\"></body></html>";
} else {
String text = new String(mBlob, Charset.forName("UTF-8"));
content = "<!DOCTYPE html><html><head><link href=\"github.css\" rel=\"stylesheet\" /></head><body><pre><code>" + Html.escapeHtml(text) + "</code></pre><script src=\"highlight.pack.js\"></script><script>hljs.initHighlightingOnLoad();</script></body></html>";
}
mFileBlobView.loadDataWithBaseURL("file:///android_asset/", content, "text/html", "utf8", null);
mToolbar.setTitle(mFileName);
mToolbar.inflateMenu(R.menu.file);
}
@Override
public void onFailure(Throwable t) {
Timber.e(t, null);
mProgressView.setVisibility(View.GONE);
Snackbar.make(getWindow().getDecorView(), R.string.file_load_error, Snackbar.LENGTH_SHORT)
.show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file);
ButterKnife.bind(this);
mProjectId = getIntent().getLongExtra(EXTRA_PROJECT_ID, -1);
mPath = getIntent().getStringExtra(EXTRA_PATH);
mRef = getIntent().getStringExtra(EXTRA_REF);
mToolbar.setNavigationIcon(R.drawable.ic_back_24dp);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch(item.getItemId()) {
case R.id.action_open:
openFile();
return true;
case R.id.action_save:
saveBlob();
return true;
}
return false;
}
});
loadData();
}
private void loadData() {
mProgressView.setVisibility(View.VISIBLE);
GitLabClient.instance().getFile(mProjectId, mPath, mRef).enqueue(mFileResponseCallback);
}
private File saveBlob() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) && mBlob != null) {
File targetFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), mFileName);
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(targetFile);
outputStream.write(mBlob);
Snackbar.make(getWindow().getDecorView(), getString(R.string.file_saved), Snackbar.LENGTH_SHORT)
.show();
return targetFile;
} catch (IOException e) {
Timber.e(e, null);
Snackbar.make(getWindow().getDecorView(), getString(R.string.save_error), Snackbar.LENGTH_SHORT)
.show();
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
}
}
}
} else {
Snackbar.make(getWindow().getDecorView(), getString(R.string.save_error), Snackbar.LENGTH_SHORT)
.show();
}
return null;
}
private void openFile() {
File file = saveBlob();
if (file == null) {
Snackbar.make(getWindow().getDecorView(), getString(R.string.open_error), Snackbar.LENGTH_SHORT)
.show();
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.fromFile(file));
String extension = fileExt(file.getName());
if (extension != null) {
intent.setTypeAndNormalize(MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension));
}
try {
startActivity(intent);
} catch (ActivityNotFoundException | SecurityException e) {
Timber.e(e, null);
Snackbar.make(getWindow().getDecorView(), getString(R.string.open_error), Snackbar.LENGTH_SHORT)
.show();
}
}
private static String fileExt(String filename) {
int extStart = filename.lastIndexOf(".") + 1;
if (extStart < 1) {
return null;
}
return filename.substring(extStart);
}
}
package com.commit451.gitlab.activities;
package com.commit451.gitlab.activity;
 
import android.app.Activity;
import android.os.Bundle;
 
import com.commit451.gitlab.tools.NavigationManager;
import com.commit451.gitlab.BuildConfig;
import com.commit451.gitlab.api.GitLabClient;
import com.commit451.gitlab.data.Prefs;
import com.commit451.gitlab.model.Account;
import com.commit451.gitlab.util.NavigationManager;
import java.util.List;
import timber.log.Timber;
 
/**
* This activity acts as switching platform for the application directing the user to the appropriate
* activity based on their logged in state
*
* Created by r0adkll on 9/18/15.
*/
public class GitlabActivity extends Activity {
 
Loading
Loading
@@ -18,13 +23,28 @@ public class GitlabActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
 
if(!Prefs.isLoggedIn(this)) {
int savedVersion = Prefs.getSavedVersion(this);
if (savedVersion != -1 && savedVersion < BuildConfig.VERSION_CODE) {
Timber.d("Performing upgrade");
performUpgrade(savedVersion, BuildConfig.VERSION_CODE);
Prefs.setSavedVersion(this);
}
List<Account> accounts = Account.getAccounts(this);
if(accounts.isEmpty()) {
NavigationManager.navigateToLogin(this);
} else {
GitLabClient.setAccount(accounts.get(0));
NavigationManager.navigateToProjects(this);
}
 
// Always finish this activity
finish();
}
/**
* Perform an upgrade from one version to another. This should only be one time upgrade things
*/
private void performUpgrade(int previousVersion, int currentVersion) {
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment