Merge pull request #34 from k0shk0sh/master [skip ci]

Update from original repo
This commit is contained in:
Igor Popov 2017-09-14 18:53:18 +03:00 committed by GitHub
commit 65ffd10c89
274 changed files with 12923 additions and 1366 deletions

View File

@ -8,7 +8,7 @@
# How to contribute & build *FastHub*
If you have a question in mind, feel free to come our public [Slack](http://rebrand.ly/fasthub-slack) channel.
If you have a question in mind, feel free to come our public [Slack](http://rebrand.ly/fasthub) channel.
### Optional

View File

@ -4,8 +4,7 @@
- Make sure that you are always on the latest version.
- Search issue before submitting a new one.
Public Slack channel: https://rebrand.ly/fasthub-slack
Discord: https://discord.gg/V6afZWf
Public Slack channel: https://rebrand.ly/fasthub
#### How to submit Issue/Feature Request to *FastHub*
- Make sure the included template is filled ( using FastHub will fill them up automatically ).

View File

@ -1,60 +0,0 @@
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Xml;
void Main(string[] args)
{
string RootDir = System.Reflection.Assembly.GetExecutingAssembly().Location;
string ResDir = Path.Combine(RootDir, @"app\src\main\res");
int TotalFiles = 0,
TotalIssues = 0;
foreach (string dir in Directory.GetDirectories(ResDir, "values-*").Where(d => File.Exists(Path.Combine(d, @"strings.xml")))) {
Console.WriteLine(@"Checking ""{0}""...", dir);
XmlDocument xmlFile = new XmlDocument();
xmlFile.Load(Path.Combine(dir, @"strings.xml"));
XmlElement xRoot = xmlFile.DocumentElement;
bool wasAdded = false;
foreach (XmlNode xmlNode in xRoot) {
if (xmlNode.Attributes == null) {
continue;
}
if (xmlNode.Attributes.Count > 0) {
foreach (XmlNode attr in xmlNode.Attributes) {
if (attr == null) {
continue;
}
if (attr.Name == "translatable") {
TotalIssues++;
PowerShell ps = PowerShell.Create();
ps.AddCommand("Add-AppveyorMessage");
ps.AddArgument(String.Format(@"Found **{0}=""{1}""** {4} in **""{2}""**. {4}File: **""{3}""**", attr.Name, attr.Value, xmlNode.OuterXml, dir, Environment.NewLine));
ps.Invoke();
Console.WriteLine(@" {0}=""{1}"" in {2}", attr.Name, attr.Value, xmlNode.OuterXml);
if (wasAdded) {
continue;
}
TotalFiles++;
wasAdded = true;
}
}
}
}
}
Console.WriteLine("Found {0} issue(s) in {1} file(s).", TotalIssues, TotalFiles);
if (TotalIssues != 0) {
PowerShell ps = PowerShell.Create();
ps.AddCommand("Add-AppveyorMessage");
ps.AddArgument(@"Please, remove the string(s) and commit again.");
ps.Invoke();
Environment.Exit(101);
}
}

6
.gitignore vendored
View File

@ -3,14 +3,10 @@
/local.properties
.DS_Store
/build
/captures
.externalNativeBuild
/gradle.properties
/.idea/
/app/google-services.json
/app/db/
/app/build/
/app/src/main/res/values/secrets.xml
/app/fastaccess-key
fast-for-github-firebase-crashreporting-7lngx-6b5be91d98.json
/fastScroller/build/
/jobdispatcher/build/

View File

@ -1,6 +1,9 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
P.S: All Fasthub Pro features shouldn't be distributed or reimplemented in any fork or librated version. These features should only be available from FastHub original project & therefore it's prohibited for anyone to provide them for free or sell them for themselves.
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

View File

@ -1,5 +1,5 @@
[![Build Status](https://travis-ci.org/k0shk0sh/FastHub.svg?branch=master)](https://travis-ci.org/k0shk0sh/FastHub) [![Build status](https://ci.appveyor.com/api/projects/status/2yhxx7hu6hju24bk?svg=true)](https://ci.appveyor.com/project/k0shk0sh/fasthub)
[![Releases](https://img.shields.io/github/release/k0shk0sh/FastHub.svg)](https://github.com/k0shk0sh/FastHub/releases/latest) [![Discord](https://img.shields.io/badge/chat-discord-7289DA.svg)](https://discord.gg/V6afZWf)
[![Build Status](https://travis-ci.org/k0shk0sh/FastHub.svg?branch=master)](https://travis-ci.org/k0shk0sh/FastHub)
[![Releases](https://img.shields.io/github/release/k0shk0sh/FastHub.svg)](https://github.com/k0shk0sh/FastHub/releases/latest) [![Slack](https://img.shields.io/badge/slack-join-e01563.svg)](http://rebrand.ly/fasthub)
![Logo](/.github/assets/feature_graphic.png?raw=true "Logo")
@ -18,10 +18,6 @@ Yet another **open-source** GitHub client app but unlike any other app, FastHub
alt="Direct apk download"
height="80">](https://github.com/k0shk0sh/FastHub/releases/latest)
#### Snapshots / Test builds
We have configured snapshots of FastHub, which can be downloaded from [AppVeyor CI](https://ci.appveyor.com/project/k0shk0sh/fasthub/build/artifacts).
# Features
- **App**
- Three login types (Basic Auth), (Access Token) or via (OAuth)
@ -37,6 +33,7 @@ We have configured snapshots of FastHub, which can be downloaded from [AppVeyor
- Wiki
- **Repositories**
- Browse & Read Wiki
- Edit, Create & Delete files (commit)
- Search Repos
- Browse and search Repos
- See your public, private and forked Repos

View File

@ -3,7 +3,7 @@ apply plugin: 'com.apollographql.android'
apply plugin: 'kotlin-android'
apply plugin: 'com.novoda.build-properties'
apply plugin: 'jacoco-android'
if (isProduction) apply plugin: 'io.fabric'
apply plugin: 'io.fabric'
buildProperties {
notThere {
@ -29,8 +29,8 @@ android {
applicationId "com.fastaccess.github"
minSdkVersion 21
targetSdkVersion 26
versionCode 403
versionName "4.0.3"
versionCode 420
versionName "4.2.0"
buildConfigString "GITHUB_CLIENT_ID", (buildProperties.secrets['github_client_id'] | buildProperties.notThere['github_client_id']).string
buildConfigString "GITHUB_SECRET", (buildProperties.secrets['github_secret'] | buildProperties.notThere['github_secret']).string
buildConfigString "IMGUR_CLIENT_ID", (buildProperties.secrets['imgur_client_id'] | buildProperties.notThere['imgur_client_id']).string
@ -59,6 +59,7 @@ android {
}
applicationIdSuffix ".debug"
versionNameSuffix "-debug"
ext.alwaysUpdateBuildId = false
}
}
@ -95,6 +96,7 @@ android {
dexOptions {
jumboMode true
javaMaxHeapSize "4g"
}
testOptions {
@ -110,7 +112,7 @@ repositories {
maven { url "https://clojars.org/repo/" }
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven { url "https://jitpack.io" }
if (isProduction) maven { url 'https://maven.fabric.io/public' }
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
@ -155,8 +157,7 @@ dependencies {
implementation "com.google.android.gms:play-services-base:${gms}"
implementation('com.github.b3er.rxfirebase:firebase-database-kotlin:11.2.0') { transitive = false }
implementation('com.github.b3er.rxfirebase:firebase-database:11.2.0') { transitive = false }
implementation 'com.firebase:firebase-jobdispatcher:0.7.0'
if (isProduction) implementation('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') { transitive = true }
implementation('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') { transitive = true }
implementation "com.github.miguelbcr:RxBillingService:0.0.3"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'org.jsoup:jsoup:1.10.2'
@ -165,6 +166,8 @@ dependencies {
implementation 'com.apollographql.apollo:apollo-rx2-support:0.4.0'
implementation 'com.jaredrummler:android-device-names:1.1.4'
implementation 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:2.1.0'
implementation 'com.airbnb.android:lottie:2.2.0'
implementation project(path: ':jobdispatcher')
compileOnly "org.projectlombok:lombok:${lombokVersion}"
kapt "org.projectlombok:lombok:${lombokVersion}"
kapt "com.evernote:android-state-processor:${state_version}"

View File

@ -71,6 +71,12 @@
-keeppackagenames org.jsoup.nodes
-keep class com.github.b3er.** { *; }
-keep class com.memoizrlabs.** { *; }
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
-dontwarn com.github.b3er.**
-dontwarn com.memoizrlabs.**
@ -124,4 +130,5 @@
-dontwarn sun.misc.Unsafe
-dontwarn com.octo.android.robospice.retrofit.RetrofitJackson**
-dontwarn retrofit.appengine.UrlFetchClient
-dontwarn icepick.**
-dontwarn icepick.**
-dontwarn com.fastaccess.ui.modules.repos.**

View File

@ -2,7 +2,8 @@
<manifest
package="com.fastaccess"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
@ -233,6 +234,31 @@
android:screenOrientation="portrait"
android:windowSoftInputMode="stateAlwaysHidden"/>
<activity
android:name=".ui.modules.repos.git.EditRepoFileActivity"
android:configChanges="keyboard|orientation|screenSize"
android:label="@string/markdown"
android:windowSoftInputMode="adjustResize"/>
<activity
android:name=".ui.modules.repos.code.commit.history.FileCommitHistoryActivity"
android:label="@string/commits"
android:parentActivityName=".ui.modules.repos.RepoPagerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.modules.repos.RepoPagerActivity"/>
</activity>
<activity
android:name="com.fastaccess.ui.modules.repos.projects.details.ProjectPagerActivity"
android:label="@string/projects"
android:parentActivityName=".ui.modules.repos.RepoPagerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.modules.repos.RepoPagerActivity"/>
</activity>
<activity
android:name=".ui.modules.parser.LinksParserActivity"
android:configChanges="keyboard|orientation|screenSize"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,90 @@
query repoProjectsOpen($owner: String!, $name: String!, $page: String) {
repository(owner: $owner, name: $name) {
projects(first: 30, states: OPEN, after: $page, orderBy: {field: CREATED_AT, direction: DESC}) {
totalCount
edges {
cursor
}
nodes {
name
number
body
createdAt
id
viewerCanUpdate
columns(first: 1) {
totalCount
}
}
}
}
}
query repoProjectsClosed($owner: String!, $name: String!, $page: String) {
repository(owner: $owner, name: $name) {
projects(first: 30, states: CLOSED, after: $page, orderBy: {field: CREATED_AT, direction: DESC}) {
totalCount
edges {
cursor
}
nodes {
name
number
body
createdAt
id
viewerCanUpdate
columns(first: 1) {
totalCount
}
}
}
}
}
query getColumns($owner: String!, $name:String!,$number:Int!) {
repository(owner: $owner, name: $name) {
project(number: $number) {
name
viewerCanUpdate
columns(first: 100) {
nodes {
name
createdAt
id
cards(first: 100) {
nodes {
note
createdAt
url
content {
... on Node {
__typename
}
... on Issue {
title
url
number
issueState: state
}
... on PullRequest {
title
url
number
PrState: state
}
... on Comment {
body
author {
login
avatarUrl
url
}
}
}
}
}
}
}
}
}
}

View File

@ -50,7 +50,7 @@ public class App extends Application {
FabricProvider.initFabric(this);
RxBillingService.register(this);
deleteDatabase("database.db");
getDataStore();//init requery before anything.
getDataStore();
setupPreference();
TypeFaceHelper.generateTypeface(this);
NotificationSchedulerJobTask.scheduleJob(this);
@ -72,7 +72,7 @@ public class App extends Application {
public ReactiveEntityStore<Persistable> getDataStore() {
if (dataStore == null) {
EntityModel model = Models.DEFAULT;
DatabaseSource source = new DatabaseSource(this, model, "FastHub-DB", 11);
DatabaseSource source = new DatabaseSource(this, model, "FastHub-DB", 13);
Configuration configuration = source.getConfiguration();
if (BuildConfig.DEBUG) {
source.setTableCreationMode(TableCreationMode.CREATE_NOT_EXISTS);

View File

@ -24,13 +24,15 @@ import lombok.Setter;
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CommentRequestModel that = (CommentRequestModel) o;
return position == that.position && (path != null ? path.equals(that.path) : that.path == null);
return (path != null ? path.equals(that.path) : that.path == null) &&
(position != null ? position.equals(that.position) : that.position == null);
}
@Override public int hashCode() {
int result = path != null ? path.hashCode() : 0;
result = 31 * result + position;
result = 31 * result + (position != null ? position.hashCode() : 0);
return result;
}

View File

@ -35,6 +35,7 @@ import static com.fastaccess.ui.widgets.DiffLineSpan.HUNK_TITLE;
public int rightLineNo;
public boolean noNewLine;
public int position;
private boolean hasCommentedOn;
@NonNull public static List<CommitLinesModel> getLines(@Nullable String text) {
ArrayList<CommitLinesModel> models = new ArrayList<>();
@ -82,7 +83,7 @@ import static com.fastaccess.ui.widgets.DiffLineSpan.HUNK_TITLE;
token = token.replace("\\ No newline at end of file", "");
}
models.add(new CommitLinesModel(token, color, token.startsWith("@@") || !addLeft ? -1 : leftLineNo,
token.startsWith("@@") || !addRight ? -1 : rightLineNo, index != -1, position));
token.startsWith("@@") || !addRight ? -1 : rightLineNo, index != -1, position, false));
}
}
}

View File

@ -0,0 +1,42 @@
package com.fastaccess.data.dao;
/**
* Created by kosh on 31/08/2017.
*/
public class CommitRequestModel {
private String message;
private String content;
private String sha;
public CommitRequestModel(String message, String content, String sha) {
this.message = message;
this.content = content;
this.sha = sha;
}
public String getSha() {
return sha;
}
public void setSha(String sha) {
this.sha = sha;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}

View File

@ -0,0 +1,51 @@
package com.fastaccess.data.dao
import android.os.Parcel
import android.os.Parcelable
/**
* Created by Hashemsergani on 01/09/2017.
*/
data class EditRepoFileModel(val login: String,
val repoId: String,
val path: String?,
val ref: String,
val sha: String?,
val contentUrl: String?,
val fileName: String?,
val isEdit: Boolean) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readByte() != 0.toByte())
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(login)
parcel.writeString(repoId)
parcel.writeString(path)
parcel.writeString(ref)
parcel.writeString(sha)
parcel.writeString(contentUrl)
parcel.writeString(fileName)
parcel.writeByte(if (isEdit) 1 else 0)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<EditRepoFileModel> {
override fun createFromParcel(parcel: Parcel): EditRepoFileModel {
return EditRepoFileModel(parcel)
}
override fun newArray(size: Int): Array<EditRepoFileModel?> {
return arrayOfNulls(size)
}
}
}

View File

@ -44,6 +44,8 @@ import com.fastaccess.ui.modules.repos.extras.branches.BranchesFragment;
import com.fastaccess.ui.modules.repos.issues.issue.RepoClosedIssuesFragment;
import com.fastaccess.ui.modules.repos.issues.issue.RepoOpenedIssuesFragment;
import com.fastaccess.ui.modules.repos.issues.issue.details.timeline.IssueTimelineFragment;
import com.fastaccess.ui.modules.repos.projects.list.RepoProjectFragment;
import com.fastaccess.ui.modules.repos.projects.columns.ProjectColumnFragment;
import com.fastaccess.ui.modules.repos.pull_requests.pull_request.RepoPullRequestFragment;
import com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.commits.PullRequestCommitsFragment;
import com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.files.PullRequestFilesFragment;
@ -152,7 +154,8 @@ import lombok.Setter;
}
@NonNull public static List<FragmentPagerAdapterModel> buildForGist(@NonNull Context context, @NonNull Gist gistsModel) {
return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.files), GistFilesListFragment.newInstance(gistsModel.getFilesAsList(), false)),
return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.files), GistFilesListFragment.newInstance(gistsModel
.getFilesAsList(), false)),
new FragmentPagerAdapterModel(context.getString(R.string.comments), GistCommentsFragment.newInstance(gistsModel.getGistId())))
.collect(Collectors.toList());
}
@ -218,6 +221,7 @@ import lombok.Setter;
new FragmentPagerAdapterModel("", ThemeFragment.Companion.newInstance(R.style.ThemeDark)),
new FragmentPagerAdapterModel("", ThemeFragment.Companion.newInstance(R.style.ThemeAmlod)),
new FragmentPagerAdapterModel("", ThemeFragment.Companion.newInstance(R.style.ThemeBluish)))
// new FragmentPagerAdapterModel("", ThemeFragment.Companion.newInstance(R.style.ThemeMidnight)))
.collect(Collectors.toList());
}
@ -228,4 +232,20 @@ import lombok.Setter;
BranchesFragment.Companion.newInstance(login, repoId, false)))
.toList();
}
@NonNull public static List<FragmentPagerAdapterModel> buildForRepoProjects(@NonNull Context context, @NonNull String repoId,
@NonNull String login) {
return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.open),
RepoProjectFragment.Companion.newInstance(login, repoId, IssueState.open)),
new FragmentPagerAdapterModel(context.getString(R.string.closed),
RepoProjectFragment.Companion.newInstance(login, repoId, IssueState.closed)))
.toList();
}
@NonNull public static List<FragmentPagerAdapterModel> buildForProjectColumns(@NonNull List<ProjectColumnModel> models, boolean isCollaborator) {
return Stream.of(models)
.map(projectColumnModel -> new FragmentPagerAdapterModel("", ProjectColumnFragment.Companion
.newInstance(projectColumnModel, isCollaborator)))
.toList();
}
}

View File

@ -61,6 +61,11 @@ public class GitCommitModel implements Parcelable {
};
@Override public String toString() {
return sha != null && sha.length() > 10 ? sha.substring(0, 10) : "N/A";
if (message != null) {
return (sha != null && sha.length() > 7 ? sha.substring(0, 7) + " - " : "") + message.split(System.lineSeparator())[0];
} else if (sha != null && sha.length() > 10) {
return sha.substring(0, 10);
}
return "N/A";
}
}

View File

@ -48,6 +48,7 @@ import static com.annimon.stream.Collectors.toList;
List<GroupedNotificationModel> models = new ArrayList<>();
if (items == null || items.isEmpty()) return models;
Map<Repo, List<Notification>> grouped = Stream.of(items)
.filter(value -> !value.isUnread())
.collect(Collectors.groupingBy(Notification::getRepository, LinkedHashMap::new,
Collectors.mapping(o -> o, toList())));
Stream.of(grouped)

View File

@ -0,0 +1,121 @@
package com.fastaccess.data.dao;
import android.os.Parcel;
import android.os.Parcelable;
import com.fastaccess.data.dao.model.User;
import java.util.Date;
/**
* Created by Hashemsergani on 11.09.17.
*/
public class ProjectCardModel implements Parcelable {
private String url;
private String columnUrl;
private String contentUrl;
private int id;
private String note;
private User creator;
private Date createdAt;
private Date updatedAt;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getColumnUrl() {
return columnUrl;
}
public void setColumnUrl(String columnUrl) {
this.columnUrl = columnUrl;
}
public String getContentUrl() {
return contentUrl;
}
public void setContentUrl(String contentUrl) {
this.contentUrl = contentUrl;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public User getCreator() {
return creator;
}
public void setCreator(User creator) {
this.creator = creator;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.url);
dest.writeString(this.columnUrl);
dest.writeString(this.contentUrl);
dest.writeInt(this.id);
dest.writeString(this.note);
dest.writeParcelable(this.creator, flags);
dest.writeLong(this.createdAt != null ? this.createdAt.getTime() : -1);
dest.writeLong(this.updatedAt != null ? this.updatedAt.getTime() : -1);
}
public ProjectCardModel() {}
protected ProjectCardModel(Parcel in) {
this.url = in.readString();
this.columnUrl = in.readString();
this.contentUrl = in.readString();
this.id = in.readInt();
this.note = in.readString();
this.creator = in.readParcelable(User.class.getClassLoader());
long tmpCreatedAt = in.readLong();
this.createdAt = tmpCreatedAt == -1 ? null : new Date(tmpCreatedAt);
long tmpUpdatedAt = in.readLong();
this.updatedAt = tmpUpdatedAt == -1 ? null : new Date(tmpUpdatedAt);
}
public static final Parcelable.Creator<ProjectCardModel> CREATOR = new Parcelable.Creator<ProjectCardModel>() {
@Override public ProjectCardModel createFromParcel(Parcel source) {return new ProjectCardModel(source);}
@Override public ProjectCardModel[] newArray(int size) {return new ProjectCardModel[size];}
};
}

View File

@ -0,0 +1,109 @@
package com.fastaccess.data.dao;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Date;
/**
* Created by Hashemsergani on 11.09.17.
*/
public class ProjectColumnModel implements Parcelable {
private long id;
private String name;
private String url;
private String projectUrl;
private String cardsUrl;
private Date createdAt;
private Date updatedAt;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getProjectUrl() {
return projectUrl;
}
public void setProjectUrl(String projectUrl) {
this.projectUrl = projectUrl;
}
public String getCardsUrl() {
return cardsUrl;
}
public void setCardsUrl(String cardsUrl) {
this.cardsUrl = cardsUrl;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.id);
dest.writeString(this.name);
dest.writeString(this.url);
dest.writeString(this.projectUrl);
dest.writeString(this.cardsUrl);
dest.writeLong(this.createdAt != null ? this.createdAt.getTime() : -1);
dest.writeLong(this.updatedAt != null ? this.updatedAt.getTime() : -1);
}
public ProjectColumnModel() {}
protected ProjectColumnModel(Parcel in) {
this.id = in.readLong();
this.name = in.readString();
this.url = in.readString();
this.projectUrl = in.readString();
this.cardsUrl = in.readString();
long tmpCreatedAt = in.readLong();
this.createdAt = tmpCreatedAt == -1 ? null : new Date(tmpCreatedAt);
long tmpUpdatedAt = in.readLong();
this.updatedAt = tmpUpdatedAt == -1 ? null : new Date(tmpUpdatedAt);
}
public static final Creator<ProjectColumnModel> CREATOR = new Creator<ProjectColumnModel>() {
@Override public ProjectColumnModel createFromParcel(Parcel source) {return new ProjectColumnModel(source);}
@Override public ProjectColumnModel[] newArray(int size) {return new ProjectColumnModel[size];}
};
}

View File

@ -0,0 +1,165 @@
package com.fastaccess.data.dao;
import android.os.Parcel;
import android.os.Parcelable;
import com.fastaccess.data.dao.model.User;
import java.util.Date;
/**
* Created by kosh on 09/09/2017.
*/
public class ProjectsModel implements Parcelable {
private String ownerUrl;
private String url;
private String htmlUrl;
private String columnsUrl;
private long id;
private String name;
private String body;
private int number;
private String state;
private User creator;
private Date createdAt;
private Date updatedAt;
public String getOwnerUrl() {
return ownerUrl;
}
public void setOwnerUrl(String ownerUrl) {
this.ownerUrl = ownerUrl;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHtmlUrl() {
return htmlUrl;
}
public void setHtmlUrl(String htmlUrl) {
this.htmlUrl = htmlUrl;
}
public String getColumnsUrl() {
return columnsUrl;
}
public void setColumnsUrl(String columnsUrl) {
this.columnsUrl = columnsUrl;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public User getCreator() {
return creator;
}
public void setCreator(User creator) {
this.creator = creator;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.ownerUrl);
dest.writeString(this.url);
dest.writeString(this.htmlUrl);
dest.writeString(this.columnsUrl);
dest.writeLong(this.id);
dest.writeString(this.name);
dest.writeString(this.body);
dest.writeInt(this.number);
dest.writeString(this.state);
dest.writeParcelable(this.creator, flags);
dest.writeLong(this.createdAt != null ? this.createdAt.getTime() : -1);
dest.writeLong(this.updatedAt != null ? this.updatedAt.getTime() : -1);
}
public ProjectsModel() {}
protected ProjectsModel(Parcel in) {
this.ownerUrl = in.readString();
this.url = in.readString();
this.htmlUrl = in.readString();
this.columnsUrl = in.readString();
this.id = in.readLong();
this.name = in.readString();
this.body = in.readString();
this.number = in.readInt();
this.state = in.readString();
this.creator = in.readParcelable(User.class.getClassLoader());
long tmpCreatedAt = in.readLong();
this.createdAt = tmpCreatedAt == -1 ? null : new Date(tmpCreatedAt);
long tmpUpdatedAt = in.readLong();
this.updatedAt = tmpUpdatedAt == -1 ? null : new Date(tmpUpdatedAt);
}
public static final Creator<ProjectsModel> CREATOR = new Creator<ProjectsModel>() {
@Override public ProjectsModel createFromParcel(Parcel source) {return new ProjectsModel(source);}
@Override public ProjectsModel[] newArray(int size) {return new ProjectsModel[size];}
};
}

View File

@ -13,7 +13,7 @@ import java.util.List;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import pr.PullRequestTimelineQuery;
import github.PullRequestTimelineQuery;
/**
* Created by Kosh on 28 Mar 2017, 9:15 PM

View File

@ -30,6 +30,7 @@ import java.util.Date;
private String htmlUrl;
private String pullRequestUrl;
private ReactionsModel reactions;
private String authorAssociation;
public ReviewCommentModel() {}
@ -161,6 +162,14 @@ import java.util.Date;
this.reactions = reactions;
}
public String getAuthorAssociation() {
return authorAssociation;
}
public void setAuthorAssociation(String authorAssociation) {
this.authorAssociation = authorAssociation;
}
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@ -174,6 +183,14 @@ import java.util.Date;
return (int) (id ^ (id >>> 32));
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel dest, int flags) {
@ -194,6 +211,7 @@ import java.util.Date;
dest.writeString(this.htmlUrl);
dest.writeString(this.pullRequestUrl);
dest.writeParcelable(this.reactions, flags);
dest.writeString(this.authorAssociation);
}
protected ReviewCommentModel(Parcel in) {
@ -216,6 +234,7 @@ import java.util.Date;
this.htmlUrl = in.readString();
this.pullRequestUrl = in.readString();
this.reactions = in.readParcelable(ReactionsModel.class.getClassLoader());
this.authorAssociation = in.readString();
}
public static final Creator<ReviewCommentModel> CREATOR = new Creator<ReviewCommentModel>() {
@ -223,12 +242,4 @@ import java.util.Date;
@Override public ReviewCommentModel[] newArray(int size) {return new ReviewCommentModel[size];}
};
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}

View File

@ -6,18 +6,39 @@ import android.support.annotation.DrawableRes;
import java.io.Serializable;
import lombok.Getter;
import lombok.Setter;
/**
* Created by Kosh on 27 Apr 2017, 6:10 PM
*/
@Getter @Setter public class TabsCountStateModel implements Parcelable, Serializable {
public class TabsCountStateModel implements Parcelable, Serializable {
private int count;
private int tabIndex;
@DrawableRes private int drawableId;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getTabIndex() {
return tabIndex;
}
public void setTabIndex(int tabIndex) {
this.tabIndex = tabIndex;
}
public int getDrawableId() {
return drawableId;
}
public void setDrawableId(int drawableId) {
this.drawableId = drawableId;
}
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

View File

@ -54,6 +54,7 @@ import static com.fastaccess.data.dao.model.Comment.UPDATED_AT;
String issueId;
String pullRequestId;
@Convert(ReactionsConverter.class) ReactionsModel reactions;
String authorAssociation;
public static Disposable saveForGist(@NonNull List<Comment> models, @NonNull String gistId) {
return RxHelper.getSingle(Single.fromPublisher(s -> {
@ -188,6 +189,7 @@ import static com.fastaccess.data.dao.model.Comment.UPDATED_AT;
dest.writeString(this.issueId);
dest.writeString(this.pullRequestId);
dest.writeParcelable(this.reactions, flags);
dest.writeString(this.authorAssociation);
}
protected AbstractComment(Parcel in) {
@ -211,6 +213,7 @@ import static com.fastaccess.data.dao.model.Comment.UPDATED_AT;
this.issueId = in.readString();
this.pullRequestId = in.readString();
this.reactions = in.readParcelable(ReactionsModel.class.getClassLoader());
this.authorAssociation = in.readString();
}
public static final Creator<Comment> CREATOR = new Creator<Comment>() {

View File

@ -143,6 +143,10 @@ import lombok.NoArgsConstructor;
.value() > 0;
}
public static void deleteAll() {
App.getInstance().getDataStore().toBlocking().delete(Notification.class).get().value();
}
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

View File

@ -120,6 +120,7 @@ import static com.fastaccess.data.dao.model.Repo.UPDATED_AT;
int networkCount;
String starredUser;
String reposOwner;
@Nullable boolean hasProjects;
public Disposable save(Repo entity) {
return Single.create(e -> {
@ -147,30 +148,32 @@ import static com.fastaccess.data.dao.model.Repo.UPDATED_AT;
public static Disposable saveStarred(@NonNull List<Repo> models, @NonNull String starredUser) {
return RxHelper.getSingle(Single.fromPublisher(s -> {
Login login = Login.getUser();
if (login != null) {
BlockingEntityStore<Persistable> dataSource = App.getInstance().getDataStore().toBlocking();
if (login.getLogin().equalsIgnoreCase(starredUser)) {
dataSource.delete(Repo.class)
.where(STARRED_USER.eq(starredUser))
.get()
.value();
if (!models.isEmpty()) {
for (Repo repo : models) {
dataSource.delete(Repo.class).where(Repo.ID.eq(repo.getId())).get().value();
repo.setStarredUser(starredUser);
dataSource.insert(repo);
try {
Login login = Login.getUser();
if (login != null) {
BlockingEntityStore<Persistable> dataSource = App.getInstance().getDataStore().toBlocking();
if (login.getLogin().equalsIgnoreCase(starredUser)) {
dataSource.delete(Repo.class)
.where(STARRED_USER.eq(starredUser))
.get()
.value();
if (!models.isEmpty()) {
for (Repo repo : models) {
dataSource.delete(Repo.class).where(Repo.ID.eq(repo.getId())).get().value();
repo.setStarredUser(starredUser);
dataSource.insert(repo);
}
}
} else {
dataSource.delete(Repo.class)
.where(STARRED_USER.notEqual(login.getLogin())
.or(STATUSES_URL.isNull()))
.get()
.value();
}
} else {
dataSource.delete(Repo.class)
.where(STARRED_USER.notEqual(login.getLogin())
.or(STATUSES_URL.isNull()))
.get()
.value();
}
}
s.onNext("");
s.onNext("");
} catch (Exception ignored) {}
s.onComplete();
})).subscribe(o -> {/*donothing*/}, Throwable::printStackTrace);
}
@ -320,6 +323,7 @@ import static com.fastaccess.data.dao.model.Repo.UPDATED_AT;
dest.writeInt(this.networkCount);
dest.writeString(this.starredUser);
dest.writeString(this.reposOwner);
dest.writeByte(this.hasProjects ? (byte) 1 : (byte) 0);
}
protected AbstractRepo(Parcel in) {
@ -404,6 +408,7 @@ import static com.fastaccess.data.dao.model.Repo.UPDATED_AT;
this.networkCount = in.readInt();
this.starredUser = in.readString();
this.reposOwner = in.readString();
this.hasProjects = in.readByte() != 0;
}
public static final Creator<Repo> CREATOR = new Creator<Repo>() {

View File

@ -10,8 +10,8 @@ import com.fastaccess.helper.ParseDateFormat;
import java.util.ArrayList;
import java.util.List;
import pr.PullRequestTimelineQuery;
import pr.type.PullRequestReviewState;
import github.PullRequestTimelineQuery;
import github.type.PullRequestReviewState;
/**
* Created by kosh on 20/08/2017.

View File

@ -7,7 +7,7 @@ import java.util.List;
import lombok.Getter;
import lombok.Setter;
import pr.PullRequestTimelineQuery;
import github.PullRequestTimelineQuery;
/**
* Created by kosh on 02/08/2017.

View File

@ -12,7 +12,8 @@ public enum FilesType {
file(R.drawable.ic_file_document),
dir(R.drawable.ic_folder),
blob(R.drawable.ic_file_document),
tree(R.drawable.ic_folder);
tree(R.drawable.ic_folder),
symlink(R.drawable.ic_file_document);
int icon;

View File

@ -0,0 +1,26 @@
package com.fastaccess.data.service
import com.fastaccess.data.dao.CommitRequestModel
import com.fastaccess.data.dao.GitCommitModel
import io.reactivex.Observable
import retrofit2.http.*
/**
* Created by kosh on 29/08/2017.
*/
interface ContentService {
@PUT("repos/{owner}/{repoId}/contents/{path}")
fun updateCreateFile(@Path("owner") owner: String,
@Path("repoId") repoId: String,
@Path("path") path: String,
@Query("branch") branch: String,
@Body body: CommitRequestModel): Observable<GitCommitModel>
@HTTP(method = "DELETE", path = "repos/{owner}/{repoId}/contents/{path}", hasBody = true)
fun deleteFile(@Path("owner") owner: String,
@Path("repoId") repoId: String,
@Path("path") path: String,
@Query("branch") branch: String,
@Body body: CommitRequestModel): Observable<GitCommitModel>
}

View File

@ -51,11 +51,11 @@ public interface IssueService {
Observable<Pageable<IssueEvent>> getTimeline(@Path("owner") String owner, @Path("repo") String repo,
@Path("issue_number") int issue_number);
@GET("repos/{owner}/{repo}/issues/{issue_number}/timeline")
@GET("repos/{owner}/{repo}/issues/{issue_number}/timeline?per_page=100")
@Headers("Accept: application/vnd.github.mockingbird-preview,application/vnd.github.VERSION.full+json," +
" application/vnd.github.squirrel-girl-preview")
Observable<IssuesPageable<JsonObject>> getTimeline(@Path("owner") String owner, @Path("repo") String repo,
@Path("issue_number") int issue_number, @Query("page") int page);
@Path("issue_number") int issue_number, @Query("page") int page);
@POST("repos/{owner}/{repo}/issues")
Observable<Issue> createIssue(@Path("owner") String owner, @Path("repo") String repo,

View File

@ -0,0 +1,36 @@
package com.fastaccess.data.service
import com.fastaccess.data.dao.Pageable
import com.fastaccess.data.dao.ProjectCardModel
import com.fastaccess.data.dao.ProjectColumnModel
import com.fastaccess.data.dao.ProjectsModel
import io.reactivex.Observable
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.Path
import retrofit2.http.Query
/**
* Created by kosh on 09/09/2017.
*/
interface ProjectsService {
@GET("repos/{owner}/{repo}/projects")
@Headers("Accept: application/vnd.github.inertia-preview+json")
fun getRepoProjects(@Path("owner") owner: String, @Path("repo") repo: String,
@Query("state") state: String?, @Query("page") page: Int): Observable<Pageable<ProjectsModel>>
@GET("orgs/{org}/projects")
@Headers("Accept: application/vnd.github.inertia-preview+json")
fun getOrgsProjects(@Path("org") org: String,
@Query("page") page: Int): Observable<Pageable<ProjectsModel>>
@GET("projects/{projectId}/columns?per_page=100")
@Headers("Accept: application/vnd.github.inertia-preview+json")
fun getProjectColumns(@Path("projectId") projectId: Long): Observable<Pageable<ProjectColumnModel>>
@GET("projects/columns/{columnId}/cards")
@Headers("Accept: application/vnd.github.inertia-preview+json")
fun getProjectCards(@Path("columnId") columnId: Long, @Query("page") page: Int): Observable<Pageable<ProjectCardModel>>
}

View File

@ -81,6 +81,12 @@ public interface RepoService {
Observable<Pageable<Commit>> getCommits(@Path("owner") String owner, @Path("repo") String repo,
@NonNull @Query("sha") String branch, @Query("page") int page);
@NonNull @GET("repos/{owner}/{repo}/commits")
Observable<Pageable<Commit>> getCommits(@Path("owner") String owner, @Path("repo") String repo,
@NonNull @Query("sha") String branch,
@NonNull @Query("path") String path,
@Query("page") int page);
@NonNull @GET("repos/{owner}/{repo}/releases")
@Headers("Accept: application/vnd.github.VERSION.full+json")
Observable<Pageable<Release>> getReleases(@Path("owner") String owner, @Path("repo") String repo, @Query("page") int page);

View File

@ -117,24 +117,36 @@ public class ActivityHelper {
}
public static void startReveal(@NonNull Activity activity, Intent intent, @NonNull View sharedElement, int requestCode) {
ActivityOptionsCompat options = ActivityOptionsCompat.makeClipRevealAnimation(sharedElement, sharedElement.getWidth() / 2,
sharedElement.getHeight() / 2,
sharedElement.getWidth(), sharedElement.getHeight());
activity.startActivityForResult(intent, requestCode, options.toBundle());
if (!PrefGetter.isAppAnimationDisabled()) {
ActivityOptionsCompat options = ActivityOptionsCompat.makeClipRevealAnimation(sharedElement, sharedElement.getWidth() / 2,
sharedElement.getHeight() / 2,
sharedElement.getWidth(), sharedElement.getHeight());
activity.startActivityForResult(intent, requestCode, options.toBundle());
} else {
activity.startActivityForResult(intent, requestCode);
}
}
public static void startReveal(@NonNull Fragment fragment, Intent intent, @NonNull View sharedElement, int requestCode) {
ActivityOptionsCompat options = ActivityOptionsCompat.makeClipRevealAnimation(sharedElement, sharedElement.getWidth() / 2,
sharedElement.getHeight() / 2,
sharedElement.getWidth(), sharedElement.getHeight());
fragment.startActivityForResult(intent, requestCode, options.toBundle());
if (!PrefGetter.isAppAnimationDisabled()) {
ActivityOptionsCompat options = ActivityOptionsCompat.makeClipRevealAnimation(sharedElement, sharedElement.getWidth() / 2,
sharedElement.getHeight() / 2,
sharedElement.getWidth(), sharedElement.getHeight());
fragment.startActivityForResult(intent, requestCode, options.toBundle());
} else {
fragment.startActivityForResult(intent, requestCode);
}
}
public static void startReveal(@NonNull Activity activity, Intent intent, @NonNull View sharedElement) {
ActivityOptionsCompat options = ActivityOptionsCompat.makeClipRevealAnimation(sharedElement, sharedElement.getWidth() / 2,
sharedElement.getHeight() / 2,
sharedElement.getWidth(), sharedElement.getHeight());
activity.startActivity(intent, options.toBundle());
if (!PrefGetter.isAppAnimationDisabled()) {
ActivityOptionsCompat options = ActivityOptionsCompat.makeClipRevealAnimation(sharedElement, sharedElement.getWidth() / 2,
sharedElement.getHeight() / 2,
sharedElement.getWidth(), sharedElement.getHeight());
activity.startActivity(intent, options.toBundle());
} else {
activity.startActivity(intent);
}
}
@SafeVarargs public static void start(@NonNull Activity activity, @NonNull Intent intent,

View File

@ -34,7 +34,9 @@ public class AppHelper {
public static void hideKeyboard(@NonNull View view) {
InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
if (inputManager != null) {
inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
@Nullable public static Fragment getFragmentByTag(@NonNull FragmentManager fragmentManager, @NonNull String tag) {
@ -47,28 +49,35 @@ public class AppHelper {
public static void cancelNotification(@NonNull Context context, int id) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(id);
if (notificationManager != null) {
notificationManager.cancel(id);
}
}
public static void cancelAllNotifications(@NonNull Context context) {
((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)).cancelAll();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.cancelAll();
}
}
public static void copyToClipboard(@NonNull Context context, @NonNull String uri) {
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(context.getString(R.string.app_name), uri);
clipboard.setPrimaryClip(clip);
Toasty.success(App.getInstance(), context.getString(R.string.success_copied)).show();
if (clipboard != null) {
clipboard.setPrimaryClip(clip);
Toasty.success(App.getInstance(), context.getString(R.string.success_copied)).show();
}
}
public static boolean isNightMode(@NonNull Resources resources) {
@PrefGetter.ThemeType int themeType = PrefGetter.getThemeType(resources);
return themeType == PrefGetter.DARK || themeType == PrefGetter.AMLOD || themeType == PrefGetter.BLUISH;
return themeType != PrefGetter.LIGHT;
}
public static String getFastHubIssueTemplate(boolean enterprise) {
String brand = (!isEmulator()) ? Build.BRAND : "Android Emulator";
String model = (!isEmulator()) ? Build.MODEL : "Android Emulator";
String model = (!isEmulator()) ? DeviceNameGetter.getInstance().getDeviceName() : "Android Emulator";
StringBuilder builder = new StringBuilder()
.append("**FastHub Version: ").append(BuildConfig.VERSION_NAME).append(enterprise ? " Enterprise**" : "**").append(" \n")
.append(!isInstalledFromPlaySore(App.getInstance()) ? "**APK Source: Unknown** \n" : "")
@ -86,7 +95,7 @@ public class AppHelper {
builder.append("- **Model:** ").append(model).append(" \n")
.append("---").append("\n\n");
if (!Locale.getDefault().getLanguage().equals(new Locale("en").getLanguage())) {
builder.append("<--")
builder.append("<!--")
.append(App.getInstance().getString(R.string.english_please))
.append("-->")
.append("\n");

View File

@ -24,8 +24,8 @@ public class PrefGetter {
public static final int LIGHT = 1;
public static final int DARK = 2;
public static final int AMLOD = 3;
public static final int MID_NIGHT_BLUE = 4;
public static final int BLUISH = 5;
public static final int BLUISH = 4;
public static final int MID_NIGHT_BLUE = 5;
public static final int RED = 1;
public static final int PINK = 2;
@ -91,7 +91,7 @@ public class PrefGetter {
private static final String OTP_CODE = "otp_code";
private static final String ENTERPRISE_OTP_CODE = "enterprise_otp_code";
private static final String APP_LANGUAGE = "app_language";
private static final String SENT_VIA = "sent_via";
private static final String SENT_VIA = "fasthub_signature";
private static final String SENT_VIA_BOX = "sent_via_enabled";
private static final String PROFILE_BACKGROUND_URL = "profile_background_url";
private static final String AMLOD_THEME_ENABLED = "amlod_theme_enabled";
@ -464,4 +464,8 @@ public class PrefGetter {
public static boolean isGistDisabled() {
return PrefHelper.getBoolean(DISABLE_AUTO_PLAY_GIF);
}
public static boolean isAppAnimationDisabled() {
return PrefHelper.getBoolean("app_animation");
}
}

View File

@ -68,7 +68,7 @@ public class ColorsProvider {
.filter(value -> value != null && !InputHelper.isEmpty(value.getKey()))
.map(Map.Entry::getKey)
.collect(Collectors.toCollection(ArrayList::new)));
lang.add(0, "All Language");
lang.add(0, "All Languages");
lang.addAll(1, POPULAR_LANG);
return lang;
}

View File

@ -3,13 +3,31 @@ package com.fastaccess.provider.fabric;
import android.content.Context;
import android.support.annotation.NonNull;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.PurchaseEvent;
import com.crashlytics.android.core.CrashlyticsCore;
import com.fastaccess.BuildConfig;
import io.fabric.sdk.android.Fabric;
/**
* Created by kosh on 14/08/2017.
*/
public class FabricProvider {
public static void initFabric(@NonNull Context context) {}//DO NOTHING IN DEBUG
public static void initFabric(@NonNull Context context) {
Fabric fabric = new Fabric.Builder(context)
.kits(new Crashlytics.Builder()
.core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
.build())
.debuggable(BuildConfig.DEBUG)
.build();
Fabric.with(fabric);
}
public static void logPurchase(@NonNull String productKey) {}//DO NOTHING IN DEBUG
public static void logPurchase(@NonNull String productKey) {
Answers.getInstance().logPurchase(new PurchaseEvent().putItemName(productKey).putSuccess(true));
}
}

View File

@ -19,22 +19,24 @@ public class PushNotificationService extends FirebaseMessagingService {
@Override public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String title = remoteMessage.getNotification().getTitle();
String body = remoteMessage.getNotification().getBody();
if (remoteMessage.getData() != null && !remoteMessage.getData().isEmpty()) {
title = title == null ? remoteMessage.getData().get("title") : title;
body = body == null ? remoteMessage.getData().get("message") : body;
if (remoteMessage != null && remoteMessage.getNotification() != null) {
String title = remoteMessage.getNotification().getTitle();
String body = remoteMessage.getNotification().getBody();
if (remoteMessage.getData() != null && !remoteMessage.getData().isEmpty()) {
title = title == null ? remoteMessage.getData().get("title") : title;
body = body == null ? remoteMessage.getData().get("message") : body;
}
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notificationBuilder.build());
}
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notificationBuilder.build());
}
}

View File

@ -10,7 +10,6 @@ import android.widget.TextView;
import com.annimon.stream.IntStream;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.Logger;
import com.fastaccess.provider.markdown.extension.emoji.EmojiExtension;
import com.fastaccess.provider.markdown.extension.mention.MentionExtension;
import com.fastaccess.provider.timeline.HtmlHelper;
@ -41,7 +40,7 @@ public class MarkDownProvider {
};
private static final String[] ARCHIVE_EXTENSIONS = {
".zip", ".7z", ".rar", ".tar.gz", ".tgz", ".tar.Z", ".tar.bz2", ".tbz2", ".tar.lzma", ".tlz", ".apk", ".jar", ".dmg"
".zip", ".7z", ".rar", ".tar.gz", ".tgz", ".tar.Z", ".tar.bz2", ".tbz2", ".tar.lzma", ".tlz", ".apk", ".jar", ".dmg", ".pdf"
};
private MarkDownProvider() {}
@ -74,14 +73,17 @@ public class MarkDownProvider {
Parser parser = Parser.builder()
.extensions(extensions)
.build();
Node node = parser.parse(markdown);
String rendered = HtmlRenderer
.builder()
.extensions(extensions)
.build()
.render(node);
Logger.e(rendered);
HtmlHelper.htmlIntoTextView(textView, rendered, (width - (textView.getPaddingStart() + textView.getPaddingEnd())));
try {
Node node = parser.parse(markdown);
String rendered = HtmlRenderer
.builder()
.extensions(extensions)
.build()
.render(node);
HtmlHelper.htmlIntoTextView(textView, rendered, (width - (textView.getPaddingStart() + textView.getPaddingEnd())));
} catch (Exception ignored) {
HtmlHelper.htmlIntoTextView(textView, markdown, (width - (textView.getPaddingStart() + textView.getPaddingEnd())));
}
}
public static void stripMdText(@NonNull TextView textView, String markdown) {
@ -252,11 +254,8 @@ public class MarkDownProvider {
}
public static void addPhoto(@NonNull EditText editText, @NonNull String title, @NonNull String link) {
String result = "![" + InputHelper.toString(title) + "](" + InputHelper.toString(link) + ")\n";
String text = InputHelper.toString(editText);
text += result;
editText.setText(text);
editText.setSelection(text.length());
String result = "![" + InputHelper.toString(title) + "](" + InputHelper.toString(link) + ")";
insertAtCursor(editText, result);
}
public static void addLink(@NonNull EditText editText) {
@ -264,11 +263,8 @@ public class MarkDownProvider {
}
public static void addLink(@NonNull EditText editText, @NonNull String title, @NonNull String link) {
String result = "[" + InputHelper.toString(title) + "](" + InputHelper.toString(link) + ")\n";
String text = InputHelper.toString(editText);
text += result;
editText.setText(text);
editText.setSelection(text.length());
String result = "[" + InputHelper.toString(title) + "](" + InputHelper.toString(link) + ")";
insertAtCursor(editText, result);
}
private static boolean hasNewLine(@NonNull String source, int selectionStart) {
@ -313,4 +309,13 @@ public class MarkDownProvider {
return false;
}
public static void insertAtCursor(@NonNull EditText editText, @NonNull String text) {
String oriContent = editText.getText().toString();
int index = editText.getSelectionStart() >= 0 ? editText.getSelectionStart() : 0;
StringBuilder builder = new StringBuilder(oriContent);
builder.insert(index, text);
editText.setText(builder.toString());
editText.setSelection(index + text.length());
}
}

View File

@ -0,0 +1,23 @@
package com.fastaccess.provider.rest
import com.apollographql.apollo.ApolloClient
import com.fastaccess.BuildConfig
import com.fastaccess.helper.PrefGetter
import com.fastaccess.provider.scheme.LinkParserHelper
/**
* Created by Hashemsergani on 12.09.17.
*/
object ApolloProdivder {
fun getApollo(enterprise: Boolean) = ApolloClient.builder()
.serverUrl("${if (enterprise && PrefGetter.isEnterprise()) {
"${LinkParserHelper.getEndpoint(PrefGetter.getEnterpriseUrl())}/"
} else {
BuildConfig.REST_URL
}}graphql")
.okHttpClient(RestProvider.provideOkHttpClient())
.build()
}

View File

@ -13,10 +13,12 @@ import com.fastaccess.BuildConfig;
import com.fastaccess.R;
import com.fastaccess.data.dao.GitHubErrorResponse;
import com.fastaccess.data.dao.NameParser;
import com.fastaccess.data.service.ContentService;
import com.fastaccess.data.service.GistService;
import com.fastaccess.data.service.IssueService;
import com.fastaccess.data.service.NotificationService;
import com.fastaccess.data.service.OrganizationService;
import com.fastaccess.data.service.ProjectsService;
import com.fastaccess.data.service.PullRequestService;
import com.fastaccess.data.service.ReactionsService;
import com.fastaccess.data.service.RepoService;
@ -178,6 +180,23 @@ public class RestProvider {
return provideRetrofit(enterprise).create(SearchService.class);
}
@NonNull public static SlackService getSlackService() {
return new Retrofit.Builder()
.baseUrl("https://ok13pknpj4.execute-api.eu-central-1.amazonaws.com/prod/")
.addConverterFactory(new GithubResponseConverter(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
.create(SlackService.class);
}
@NonNull public static ContentService getContentService(boolean enterprise) {
return provideRetrofit(enterprise).create(ContentService.class);
}
@NonNull public static ProjectsService getProjectsService(boolean enterprise) {
return provideRetrofit(enterprise).create(ProjectsService.class);
}
@Nullable public static GitHubErrorResponse getErrorResponse(@NonNull Throwable throwable) {
ResponseBody body = null;
if (throwable instanceof HttpException) {
@ -191,15 +210,6 @@ public class RestProvider {
return null;
}
@NonNull public static SlackService getSlackService() {
return new Retrofit.Builder()
.baseUrl("https://ok13pknpj4.execute-api.eu-central-1.amazonaws.com/prod/")
.addConverterFactory(new GithubResponseConverter(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
.create(SlackService.class);
}
public static void clearHttpClient() {
okHttpClient = null;
}

View File

@ -4,6 +4,7 @@ import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.webkit.MimeTypeMap;
import com.annimon.stream.Optional;
import com.annimon.stream.Stream;
@ -34,33 +35,35 @@ public class LinkParserHelper {
}
@NonNull static Uri getBlobBuilder(@NonNull Uri uri) {
boolean isSvg = "svg".equalsIgnoreCase(MimeTypeMap.getFileExtensionFromUrl(uri.toString()));
List<String> segments = uri.getPathSegments();
Uri.Builder urlBuilder = null;
if (uri.getAuthority().equalsIgnoreCase(HOST_DEFAULT)) {
String owner = segments.get(0);
String repo = segments.get(1);
String branch = segments.get(3);
urlBuilder = new Uri.Builder();
urlBuilder.scheme("https")
.authority(API_AUTHORITY)
.appendPath("repos")
.appendPath(owner)
.appendPath(repo)
.appendPath("contents");
for (int i = 4; i < segments.size(); i++) {
urlBuilder.appendPath(segments.get(i));
}
if (uri.getQueryParameterNames() != null) {
for (String query : uri.getQueryParameterNames()) {
urlBuilder.appendQueryParameter(query, uri.getQueryParameter(query));
}
}
if (uri.getEncodedFragment() != null) {
urlBuilder.encodedFragment(uri.getEncodedFragment());
}
urlBuilder.appendQueryParameter("ref", branch);
if (isSvg) {
Uri svgBlob = Uri.parse(uri.toString().replace("blob/", ""));
return svgBlob.buildUpon().authority(RAW_AUTHORITY).build();
}
return urlBuilder != null ? urlBuilder.build() : uri;
Uri.Builder urlBuilder = new Uri.Builder();
String owner = segments.get(0);
String repo = segments.get(1);
String branch = segments.get(3);
urlBuilder.scheme("https")
.authority(API_AUTHORITY)
.appendPath("repos")
.appendPath(owner)
.appendPath(repo)
.appendPath("contents");
for (int i = 4; i < segments.size(); i++) {
urlBuilder.appendPath(segments.get(i));
}
if (uri.getQueryParameterNames() != null) {
for (String query : uri.getQueryParameterNames()) {
urlBuilder.appendQueryParameter(query, uri.getQueryParameter(query));
}
}
if (uri.getEncodedFragment() != null) {
urlBuilder.encodedFragment(uri.getEncodedFragment());
}
urlBuilder.appendQueryParameter("ref", branch);
return urlBuilder.build();
}
public static boolean isEnterprise(@Nullable String url) {

View File

@ -131,7 +131,6 @@ public class SchemeParser {
if (MarkDownProvider.isArchive(data.toString())) return null;
if (TextUtils.equals(authority, HOST_DEFAULT) || TextUtils.equals(authority, RAW_AUTHORITY) ||
TextUtils.equals(authority, API_AUTHORITY) || isEnterprise) {
Logger.e(data);
Intent trending = getTrending(context, data);
Intent userIntent = getUser(context, data);
Intent repoIssues = getRepoIssueIntent(context, data);
@ -178,6 +177,11 @@ public class SchemeParser {
return null;
}
private static boolean getInvitationIntent(@NonNull Uri uri) {
List<String> segments = uri.getPathSegments();
return (segments != null && segments.size() == 3) && "invitations".equalsIgnoreCase(uri.getLastPathSegment());
}
@Nullable private static Intent getPullRequestIntent(@NonNull Context context, @NonNull Uri uri, boolean showRepoBtn) {
List<String> segments = uri.getPathSegments();
if (segments == null || segments.size() < 3) return null;
@ -241,10 +245,23 @@ public class SchemeParser {
@Nullable private static Intent getRepo(@NonNull Context context, @NonNull Uri uri) {
List<String> segments = uri.getPathSegments();
if (segments == null || segments.size() < 2 || segments.size() > 2) return null;
if (segments == null || segments.size() < 2 || segments.size() > 3) return null;
String owner = segments.get(0);
String repoName = segments.get(1);
return RepoPagerActivity.createIntent(context, repoName, owner);
if (segments.size() == 3) {
String lastPath = uri.getLastPathSegment();
if ("network".equalsIgnoreCase(lastPath)) {
return RepoPagerActivity.createIntent(context, repoName, owner, RepoPagerMvp.CODE, 3);
} else if ("stargazers".equalsIgnoreCase(lastPath)) {
return RepoPagerActivity.createIntent(context, repoName, owner, RepoPagerMvp.CODE, 2);
} else if ("watchers".equalsIgnoreCase(lastPath)) {
return RepoPagerActivity.createIntent(context, repoName, owner, RepoPagerMvp.CODE, 1);
} else {
return null;
}
} else {
return RepoPagerActivity.createIntent(context, repoName, owner);
}
}
@Nullable private static Intent getWiki(@NonNull Context context, @NonNull Uri uri) {
@ -264,6 +281,9 @@ public class SchemeParser {
*/
@Nullable private static Intent getGeneralRepo(@NonNull Context context, @NonNull Uri uri) {
//TODO parse deeper links to their associate views. meantime fallback to repoPage
if (getInvitationIntent(uri)) {
return null;
}
boolean isEnterprise = PrefGetter.isEnterprise() && Uri.parse(LinkParserHelper.getEndpoint(PrefGetter.getEnterpriseUrl())).getAuthority()
.equalsIgnoreCase(uri.getAuthority());
if (uri.getAuthority().equals(HOST_DEFAULT) || uri.getAuthority().equals(API_AUTHORITY) || isEnterprise) {
@ -359,6 +379,7 @@ public class SchemeParser {
}
if (segmentTwo.equals("blob") || segmentTwo.equals("tree")) {
Uri urlBuilder = getBlobBuilder(uri);
Logger.e(urlBuilder);
return CodeViewerActivity.createIntent(context, urlBuilder.toString(), uri.toString());
} else {
String authority = uri.getAuthority();

View File

@ -1,21 +1,20 @@
package com.fastaccess.provider.tasks.notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import com.annimon.stream.Stream;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.fastaccess.R;
import com.fastaccess.data.dao.model.Comment;
import com.fastaccess.data.dao.model.Login;
@ -191,21 +190,13 @@ public class NotificationSchedulerJobTask extends JobService {
}
private void showNotificationWithoutComment(Context context, int accentColor, Notification thread, String iconUrl) {
if (!InputHelper.isEmpty(iconUrl)) {
withoutComments(null, thread, context, accentColor);
} else {
Glide.with(context).load(iconUrl).asBitmap()
.into(new SimpleTarget<Bitmap>() {
@Override public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
withoutComments(resource, thread, context, accentColor);
}
});
}
withoutComments(thread, context, accentColor);
}
private void withoutComments(Bitmap bitmap, Notification thread, Context context, int accentColor) {
android.app.Notification toAdd = getNotification(thread.getSubject().getTitle(), thread.getRepository().getFullName())
.setLargeIcon(bitmap == null ? BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher) : bitmap)
private void withoutComments(Notification thread, Context context, int accentColor) {
android.app.Notification toAdd = getNotification(thread.getSubject().getTitle(), thread.getRepository().getFullName(),
thread.getRepository() != null ? thread.getRepository().getFullName() : "general")
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentIntent(getPendingIntent(thread.getId(), thread.getSubject().getUrl()))
.addAction(R.drawable.ic_github, context.getString(R.string.open), getPendingIntent(thread.getId(), thread
.getSubject().getUrl()))
@ -220,20 +211,13 @@ public class NotificationSchedulerJobTask extends JobService {
}
private void getNotificationWithComment(Context context, int accentColor, Notification thread, Comment comment, String url) {
if (!InputHelper.isEmpty(url)) {
Glide.with(context).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {
@Override public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
withComments(resource, comment, context, thread, accentColor);
}
});
} else {
withComments(null, comment, context, thread, accentColor);
}
withComments(comment, context, thread, accentColor);
}
private void withComments(Bitmap bitmap, Comment comment, Context context, Notification thread, int accentColor) {
android.app.Notification toAdd = getNotification(comment.getUser() != null ? comment.getUser().getLogin() : "", comment.getBody())
.setLargeIcon(bitmap == null ? BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher) : bitmap)
private void withComments(Comment comment, Context context, Notification thread, int accentColor) {
android.app.Notification toAdd = getNotification(comment.getUser() != null ? comment.getUser().getLogin() : "", comment.getBody(),
thread.getRepository() != null ? thread.getRepository().getFullName() : "general")
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setSmallIcon(R.drawable.ic_notification)
.setStyle(new NotificationCompat.BigTextStyle()
.setBigContentTitle(comment.getUser() != null ? comment.getUser().getLogin() : "")
@ -254,7 +238,8 @@ public class NotificationSchedulerJobTask extends JobService {
private android.app.Notification getSummaryGroupNotification(@NonNull Notification thread, int accentColor, boolean toNotificationActivity) {
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
new Intent(getApplicationContext(), NotificationActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
return getNotification(thread.getSubject().getTitle(), thread.getRepository().getFullName())
return getNotification(thread.getSubject().getTitle(), thread.getRepository().getFullName(),
thread.getRepository() != null ? thread.getRepository().getFullName() : "general")
.setDefaults(PrefGetter.isNotificationSoundEnabled() ? NotificationCompat.DEFAULT_ALL : 0)
.setSound(PrefGetter.getNotificationSound(), AudioManager.STREAM_NOTIFICATION)
.setContentIntent(toNotificationActivity ? pendingIntent : getPendingIntent(thread.getId(), thread.getSubject().getUrl()))
@ -271,8 +256,8 @@ public class NotificationSchedulerJobTask extends JobService {
.build();
}
private NotificationCompat.Builder getNotification(@NonNull String title, @NonNull String message) {
return new NotificationCompat.Builder(this, title)
private NotificationCompat.Builder getNotification(@NonNull String title, @NonNull String message, @NonNull String channelName) {
return new NotificationCompat.Builder(this, channelName)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true);
@ -280,7 +265,15 @@ public class NotificationSchedulerJobTask extends JobService {
private void showNotification(long id, android.app.Notification notification) {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(InputHelper.getSafeIntId(id), notification);
if (notificationManager != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(String.valueOf(id),
notification.getChannelId(), NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setShowBadge(true);
notificationManager.createNotificationChannel(notificationChannel);
}
notificationManager.notify(InputHelper.getSafeIntId(id), notification);
}
}
private PendingIntent getReadOnlyPendingIntent(long id, @NonNull String url) {

View File

@ -3,6 +3,7 @@ package com.fastaccess.provider.tasks.version
import android.app.IntentService
import android.content.Intent
import android.widget.Toast
import com.fastaccess.App
import com.fastaccess.BuildConfig
import com.fastaccess.R
import com.fastaccess.data.dao.model.Release
@ -19,7 +20,7 @@ class CheckVersionService : IntentService("CheckVersionService") {
.getLatestRelease("k0shk0sh", "FastHub"))
.subscribe({ t: Release? ->
t?.let {
Toast.makeText(this, if (BuildConfig.VERSION_NAME.contains(it.tagName))
Toast.makeText(App.getInstance(), if (BuildConfig.VERSION_NAME.contains(it.tagName))
R.string.up_to_date else R.string.new_version, Toast.LENGTH_LONG).show()
}
}, { throwable -> throwable.printStackTrace() })

View File

@ -13,7 +13,6 @@ import com.fastaccess.ui.base.BaseActivity
import com.fastaccess.ui.modules.login.LoginActivity
import com.fastaccess.ui.modules.login.chooser.LoginChooserActivity
import com.fastaccess.ui.modules.main.donation.DonateActivity
import com.fastaccess.ui.modules.reviews.changes.ReviewChangesActivity
/**
* Created by Kosh on 07 Jun 2017, 6:52 PM
@ -44,7 +43,7 @@ object ThemeEngine {
PrefGetter.LIGHT -> activity.setTheme(R.style.AppTheme_AboutActivity_Light)
PrefGetter.DARK -> activity.setTheme(R.style.AppTheme_AboutActivity_Dark)
PrefGetter.AMLOD -> activity.setTheme(R.style.AppTheme_AboutActivity_Amlod)
PrefGetter.MID_NIGHT_BLUE -> activity.setTheme(R.style.AppTheme_AboutActivity_MidNightBlue)
PrefGetter.MID_NIGHT_BLUE -> activity.setTheme(R.style.AppTheme_AboutActivity_Midnight)
PrefGetter.BLUISH -> activity.setTheme(R.style.AppTheme_AboutActivity_Bluish)
}
setTaskDescription(activity)
@ -89,7 +88,8 @@ object ThemeEngine {
PrefGetter.BLUE -> return R.style.ThemeDark
PrefGetter.LIGHT_BLUE -> return R.style.ThemeDark_LightBlue
PrefGetter.CYAN -> return R.style.ThemeDark_Cyan
PrefGetter.TEAL, PrefGetter.GREEN -> return R.style.ThemeDark_Green
PrefGetter.GREEN -> return R.style.ThemeDark_Green
PrefGetter.TEAL -> return R.style.ThemeDark_Teal
PrefGetter.LIGHT_GREEN -> return R.style.ThemeDark_LightGreen
PrefGetter.LIME -> return R.style.ThemeDark_Lime
PrefGetter.YELLOW -> return R.style.ThemeDark_Yellow
@ -107,7 +107,8 @@ object ThemeEngine {
PrefGetter.BLUE -> return R.style.ThemeAmlod
PrefGetter.LIGHT_BLUE -> return R.style.ThemeAmlod_LightBlue
PrefGetter.CYAN -> return R.style.ThemeAmlod_Cyan
PrefGetter.TEAL, PrefGetter.GREEN -> return R.style.ThemeAmlod_Green
PrefGetter.TEAL -> return R.style.ThemeAmlod_Teal
PrefGetter.GREEN -> return R.style.ThemeAmlod_Green
PrefGetter.LIGHT_GREEN -> return R.style.ThemeAmlod_LightGreen
PrefGetter.LIME -> return R.style.ThemeAmlod_Lime
PrefGetter.YELLOW -> return R.style.ThemeAmlod_Yellow
@ -117,22 +118,23 @@ object ThemeEngine {
else -> return R.style.ThemeAmlod
}
PrefGetter.MID_NIGHT_BLUE -> when (themeColor) {
PrefGetter.RED -> return R.style.ThemeMidNighBlue_Red
PrefGetter.PINK -> return R.style.ThemeMidNighBlue_Pink
PrefGetter.PURPLE -> return R.style.ThemeMidNighBlue_Purple
PrefGetter.DEEP_PURPLE -> return R.style.ThemeMidNighBlue_DeepPurple
PrefGetter.INDIGO -> return R.style.ThemeMidNighBlue_Indigo
PrefGetter.BLUE -> return R.style.ThemeMidNighBlue
PrefGetter.LIGHT_BLUE -> return R.style.ThemeMidNighBlue_LightBlue
PrefGetter.CYAN -> return R.style.ThemeMidNighBlue_Cyan
PrefGetter.TEAL, PrefGetter.GREEN -> return R.style.ThemeMidNighBlue_Green
PrefGetter.LIGHT_GREEN -> return R.style.ThemeMidNighBlue_LightGreen
PrefGetter.LIME -> return R.style.ThemeMidNighBlue_Lime
PrefGetter.YELLOW -> return R.style.ThemeMidNighBlue_Yellow
PrefGetter.AMBER -> return R.style.ThemeMidNighBlue_Amber
PrefGetter.ORANGE -> return R.style.ThemeMidNighBlue_Orange
PrefGetter.DEEP_ORANGE -> return R.style.ThemeMidNighBlue_DeepOrange
else -> return R.style.ThemeMidNighBlue
PrefGetter.RED -> return R.style.ThemeMidnight_Red
PrefGetter.PINK -> return R.style.ThemeMidnight_Pink
PrefGetter.PURPLE -> return R.style.ThemeMidnight_Purple
PrefGetter.DEEP_PURPLE -> return R.style.ThemeMidnight_DeepPurple
PrefGetter.INDIGO -> return R.style.ThemeMidnight_Indigo
PrefGetter.BLUE -> return R.style.ThemeMidnight
PrefGetter.LIGHT_BLUE -> return R.style.ThemeMidnight_LightBlue
PrefGetter.CYAN -> return R.style.ThemeMidnight_Cyan
PrefGetter.TEAL -> return R.style.ThemeMidnight_Teal
PrefGetter.GREEN -> return R.style.ThemeMidnight_Green
PrefGetter.LIGHT_GREEN -> return R.style.ThemeMidnight_LightGreen
PrefGetter.LIME -> return R.style.ThemeMidnight_Lime
PrefGetter.YELLOW -> return R.style.ThemeMidnight_Yellow
PrefGetter.AMBER -> return R.style.ThemeMidnight_Amber
PrefGetter.ORANGE -> return R.style.ThemeMidnight_Orange
PrefGetter.DEEP_ORANGE -> return R.style.ThemeMidnight_DeepOrange
else -> return R.style.ThemeMidnight
}
PrefGetter.BLUISH -> when (themeColor) {
PrefGetter.RED -> return R.style.ThemeBluish_Red
@ -143,7 +145,8 @@ object ThemeEngine {
PrefGetter.BLUE -> return R.style.ThemeBluish
PrefGetter.LIGHT_BLUE -> return R.style.ThemeBluish_LightBlue
PrefGetter.CYAN -> return R.style.ThemeBluish_Cyan
PrefGetter.TEAL, PrefGetter.GREEN -> return R.style.ThemeBluish_Green
PrefGetter.TEAL -> return R.style.ThemeBluish_Teal
PrefGetter.GREEN -> return R.style.ThemeBluish_Green
PrefGetter.LIGHT_GREEN -> return R.style.ThemeBluish_LightGreen
PrefGetter.LIME -> return R.style.ThemeBluish_Lime
PrefGetter.YELLOW -> return R.style.ThemeBluish_Yellow
@ -186,7 +189,8 @@ object ThemeEngine {
PrefGetter.BLUE -> return R.style.DialogThemeDark
PrefGetter.LIGHT_BLUE -> return R.style.DialogThemeDark_LightBlue
PrefGetter.CYAN -> return R.style.DialogThemeDark_Cyan
PrefGetter.TEAL, PrefGetter.GREEN -> return R.style.DialogThemeDark_Green
PrefGetter.TEAL -> return R.style.DialogThemeDark_Teal
PrefGetter.GREEN -> return R.style.DialogThemeDark_Green
PrefGetter.LIGHT_GREEN -> return R.style.DialogThemeDark_LightGreen
PrefGetter.LIME -> return R.style.DialogThemeDark_Lime
PrefGetter.YELLOW -> return R.style.DialogThemeDark_Yellow
@ -204,7 +208,8 @@ object ThemeEngine {
PrefGetter.BLUE -> return R.style.DialogThemeAmlod
PrefGetter.LIGHT_BLUE -> return R.style.DialogThemeAmlod_LightBlue
PrefGetter.CYAN -> return R.style.DialogThemeAmlod_Cyan
PrefGetter.TEAL, PrefGetter.GREEN -> return R.style.DialogThemeAmlod_Green
PrefGetter.TEAL -> return R.style.DialogThemeAmlod_Teal
PrefGetter.GREEN -> return R.style.DialogThemeAmlod_Green
PrefGetter.LIGHT_GREEN -> return R.style.DialogThemeAmlod_LightGreen
PrefGetter.LIME -> return R.style.DialogThemeAmlod_Lime
PrefGetter.YELLOW -> return R.style.DialogThemeAmlod_Yellow
@ -214,21 +219,22 @@ object ThemeEngine {
else -> return R.style.DialogThemeAmlod
}
PrefGetter.MID_NIGHT_BLUE -> when (themeColor) {
PrefGetter.RED -> return R.style.DialogThemeLight_Red
PrefGetter.PINK -> return R.style.DialogThemeLight_Pink
PrefGetter.PURPLE -> return R.style.DialogThemeLight_Purple
PrefGetter.DEEP_PURPLE -> return R.style.DialogThemeLight_DeepPurple
PrefGetter.INDIGO -> return R.style.DialogThemeLight_Indigo
PrefGetter.BLUE -> return R.style.DialogThemeLight
PrefGetter.LIGHT_BLUE -> return R.style.DialogThemeLight_LightBlue
PrefGetter.CYAN -> return R.style.DialogThemeLight_Cyan
PrefGetter.TEAL, PrefGetter.GREEN -> return R.style.DialogThemeLight_Green
PrefGetter.LIGHT_GREEN -> return R.style.DialogThemeLight_LightGreen
PrefGetter.LIME -> return R.style.DialogThemeLight_Lime
PrefGetter.YELLOW -> return R.style.DialogThemeLight_Yellow
PrefGetter.AMBER -> return R.style.DialogThemeLight_Amber
PrefGetter.ORANGE -> return R.style.DialogThemeLight_Orange
PrefGetter.DEEP_ORANGE -> return R.style.DialogThemeLight_DeepOrange
PrefGetter.RED -> return R.style.DialogThemeMidnight_Red
PrefGetter.PINK -> return R.style.DialogThemeMidnight_Pink
PrefGetter.PURPLE -> return R.style.DialogThemeMidnight_Purple
PrefGetter.DEEP_PURPLE -> return R.style.DialogThemeMidnight_DeepPurple
PrefGetter.INDIGO -> return R.style.DialogThemeMidnight_Indigo
PrefGetter.BLUE -> return R.style.DialogThemeMidnight
PrefGetter.LIGHT_BLUE -> return R.style.DialogThemeMidnight_LightBlue
PrefGetter.CYAN -> return R.style.DialogThemeMidnight_Cyan
PrefGetter.TEAL -> return R.style.DialogThemeMidnight_Teal
PrefGetter.GREEN -> return R.style.DialogThemeMidnight_Green
PrefGetter.LIGHT_GREEN -> return R.style.DialogThemeMidnight_LightGreen
PrefGetter.LIME -> return R.style.DialogThemeMidnight_Lime
PrefGetter.YELLOW -> return R.style.DialogThemeMidnight_Yellow
PrefGetter.AMBER -> return R.style.DialogThemeMidnight_Amber
PrefGetter.ORANGE -> return R.style.DialogThemeMidnight_Orange
PrefGetter.DEEP_ORANGE -> return R.style.DialogThemeMidnight_DeepOrange
else -> return R.style.DialogThemeLight
}
PrefGetter.BLUISH -> when (themeColor) {
@ -240,7 +246,8 @@ object ThemeEngine {
PrefGetter.BLUE -> return R.style.DialogThemeBluish
PrefGetter.LIGHT_BLUE -> return R.style.DialogThemeBluish_LightBlue
PrefGetter.CYAN -> return R.style.DialogThemeBluish_Cyan
PrefGetter.TEAL, PrefGetter.GREEN -> return R.style.DialogThemeBluish_Green
PrefGetter.TEAL -> return R.style.DialogThemeBluish_Teal
PrefGetter.GREEN -> return R.style.DialogThemeBluish_Green
PrefGetter.LIGHT_GREEN -> return R.style.DialogThemeBluish_LightGreen
PrefGetter.LIME -> return R.style.DialogThemeBluish_Lime
PrefGetter.YELLOW -> return R.style.DialogThemeBluish_Yellow
@ -259,5 +266,5 @@ object ThemeEngine {
}
private fun hasTheme(activity: BaseActivity<*, *>) = (activity is LoginChooserActivity || activity is LoginActivity ||
activity is DonateActivity || activity is ReviewChangesActivity)
activity is DonateActivity)
}

View File

@ -47,13 +47,15 @@ public class HtmlHelper {
public static void htmlIntoTextView(@NonNull TextView textView, @NonNull String html, int width) {
registerClickEvent(textView);
if (textView.getMeasuredWidth() > 0) {
if (textView.getWidth() > 100) {
textView.setText(initHtml(textView, getActualWidth(textView)).fromHtml(format(html).toString()));
} else {
textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override public void onGlobalLayout() {
textView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
textView.setText(initHtml(textView, getActualWidth(textView)).fromHtml(format(html).toString()));
textView.setText(initHtml(textView, textView.getWidth() > 100 ? getActualWidth(textView) : (width + convertDpToPx(textView
.getContext(), 16)))
.fromHtml(format(html).toString()));
}
});
}
@ -92,7 +94,7 @@ public class HtmlHelper {
}
private static int getActualWidth(TextView textView) {
return textView.getMeasuredWidth() - (convertDpToPx(textView.getContext(), 16));
return textView.getWidth() - (convertDpToPx(textView.getContext(), 16));
}
private static HtmlSpanner initHtml(@NonNull TextView textView, int width) {

View File

@ -86,7 +86,8 @@ public class TimelineProvider {
} else if (event == IssueEventType.assigned || event == IssueEventType.unassigned) {
spannableBuilder
.append(" ");
if (user != null && user.getLogin().equalsIgnoreCase(issueEventModel.getAssignee().getLogin())) {
if ((user != null && issueEventModel.getAssignee() != null) && user.getLogin()
.equalsIgnoreCase(issueEventModel.getAssignee().getLogin())) {
spannableBuilder
.append(event == IssueEventType.assigned ? "self-assigned this" : "removed their assignment");
} else {
@ -94,7 +95,7 @@ public class TimelineProvider {
.append(event == IssueEventType.assigned ? "assigned" : "unassigned");
spannableBuilder
.append(" ")
.bold(issueEventModel.getAssignee().getLogin());
.bold(issueEventModel.getAssignee() != null ? issueEventModel.getAssignee().getLogin() : "");
}
} else if (event == IssueEventType.locked || event == IssueEventType.unlocked) {
spannableBuilder
@ -133,11 +134,13 @@ public class TimelineProvider {
} else if (event == IssueEventType.cross_referenced) {
SourceModel sourceModel = issueEventModel.getSource();
if (sourceModel != null) {
String type = sourceModel.getType();
SpannableBuilder title = SpannableBuilder.builder();
if (sourceModel.getIssue() != null) {
if (sourceModel.getPullRequest() != null) {
if (sourceModel.getIssue() != null) title.url("#" + sourceModel.getIssue().getNumber());
type = "pull request";
} else if (sourceModel.getIssue() != null) {
title.url("#" + sourceModel.getIssue().getNumber());
} else if (sourceModel.getPullRequest() != null) {
title.url("#" + sourceModel.getPullRequest().getNumber());
} else if (sourceModel.getCommit() != null) {
title.url(substring(sourceModel.getCommit().getSha()));
} else if (sourceModel.getRepository() != null) {
@ -147,7 +150,7 @@ public class TimelineProvider {
spannableBuilder.append(" ")
.append(thisString)
.append(" in ")
.append(sourceModel.getType())
.append(type)
.append(" ")
.append(title);
}

View File

@ -8,7 +8,6 @@ import com.fastaccess.helper.InputHelper;
import com.fastaccess.provider.timeline.handler.drawable.DrawableGetter;
import net.nightwhistler.htmlspanner.TagNodeHandler;
import net.nightwhistler.htmlspanner.spans.CenterSpan;
import org.htmlcleaner.TagNode;
@ -33,9 +32,7 @@ import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
if (!InputHelper.isEmpty(src)) {
builder.append("");
if (isNull()) return;
CenterSpan centerSpan = new CenterSpan();
DrawableGetter imageGetter = new DrawableGetter(textView);
builder.setSpan(centerSpan, start, builder.length(), SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new ImageSpan(imageGetter.getDrawable(src)), start, builder.length(), SPAN_EXCLUSIVE_EXCLUSIVE);
appendNewLine(builder);
}

View File

@ -144,12 +144,13 @@ public class TableHandler extends TagNodeHandler {
int rowHeight = 0;
for (Spanned cell : row) {
StaticLayout layout = new StaticLayout(cell, textPaint, columnWidth
- 2 * PADDING, Alignment.ALIGN_NORMAL, 1f, 0f, true);
if (layout.getHeight() > rowHeight) {
rowHeight = layout.getHeight();
if (columnWidth > 0) {
for (Spanned cell : row) {
StaticLayout layout = new StaticLayout(cell, textPaint, columnWidth
- 2 * PADDING, Alignment.ALIGN_NORMAL, 1f, 0f, true);
if (layout.getHeight() > rowHeight) {
rowHeight = layout.getHeight();
}
}
}

View File

@ -8,6 +8,7 @@ import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.fastaccess.R;
import com.fastaccess.helper.PrefGetter;
import java.lang.ref.WeakReference;
@ -23,22 +24,13 @@ class GlideDrawableTarget extends SimpleTarget<GlideDrawable> {
@Override public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
if (container != null && container.get() != null) {
TextView textView = container.get();
float width;
float height;
if (resource.getIntrinsicWidth() >= textView.getWidth()) {
float downScale = (float) resource.getIntrinsicWidth() / textView.getWidth();
width = (float) resource.getIntrinsicWidth() / downScale;
height = (float) resource.getIntrinsicHeight() / downScale;
} else {
float multiplier = (float) textView.getWidth() / resource.getIntrinsicWidth();
width = (float) resource.getIntrinsicWidth() * multiplier;
height = (float) resource.getIntrinsicHeight() * multiplier;
}
Rect rect = new Rect(0, 0, (int) Math.round(width / 1.3), (int) Math.round(height / 1.3));
float width = (float) (resource.getIntrinsicWidth() / 1.3);
float height = (float) (resource.getIntrinsicHeight() / 1.3);
Rect rect = new Rect(0, 0, Math.round(width), Math.round(height));
resource.setBounds(rect);
urlDrawable.setBounds(rect);
urlDrawable.setDrawable(resource);
if (resource.isAnimated()) {
if (resource.isAnimated() && !PrefGetter.isGistDisabled()) {
urlDrawable.setCallback((Drawable.Callback) textView.getTag(R.id.drawable_callback));
resource.setLoopCount(GlideDrawable.LOOP_FOREVER);
resource.start();

View File

@ -0,0 +1,21 @@
package com.fastaccess.ui.adapter
import android.view.ViewGroup
import com.fastaccess.data.dao.ProjectCardModel
import com.fastaccess.ui.adapter.viewholder.ColumnCardViewHolder
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
/**
* Created by Hashemsergani on 11.09.17.
*/
class ColumnCardAdapter(date: ArrayList<ProjectCardModel>, val isOwner: Boolean) : BaseRecyclerAdapter<ProjectCardModel,
ColumnCardViewHolder, BaseViewHolder.OnItemClickListener<ProjectCardModel>>(date) {
override fun viewHolder(parent: ViewGroup, viewType: Int): ColumnCardViewHolder = ColumnCardViewHolder.newInstance(parent, this, isOwner)
override fun onBindView(holder: ColumnCardViewHolder?, position: Int) {
holder?.bind(data[position])
}
}

View File

@ -47,8 +47,11 @@ class EmojiAdapter(listener: BaseViewHolder.OnItemClickListener<Emoji>)
return results
}
@Suppress("UNCHECKED_CAST")
override fun publishResults(var1: CharSequence, results: Filter.FilterResults) {
insertItems(results.values as List<Emoji>)
results.values?.let {
insertItems(it as List<Emoji>)
}
}
}
}

View File

@ -4,7 +4,7 @@ import android.view.ViewGroup
import com.fastaccess.ui.adapter.viewholder.ProfilePinnedReposViewHolder
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
import pr.GetPinnedReposQuery
import github.GetPinnedReposQuery
import java.text.NumberFormat
/**

View File

@ -0,0 +1,20 @@
package com.fastaccess.ui.adapter
import android.view.ViewGroup
import com.fastaccess.ui.adapter.viewholder.ProjectViewHolder
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
import github.RepoProjectsOpenQuery
/**
* Created by kosh on 09/09/2017.
*/
class ProjectsAdapter(data: ArrayList<RepoProjectsOpenQuery.Node>) :
BaseRecyclerAdapter<RepoProjectsOpenQuery.Node, ProjectViewHolder, BaseViewHolder.OnItemClickListener<RepoProjectsOpenQuery.Node>>(data) {
override fun viewHolder(parent: ViewGroup, viewType: Int): ProjectViewHolder = ProjectViewHolder.newInstance(parent, this)
override fun onBindView(holder: ProjectViewHolder?, position: Int) {
holder?.bind(data[position])
}
}

View File

@ -0,0 +1,37 @@
package com.fastaccess.ui.adapter.viewholder
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import butterknife.BindView
import com.fastaccess.R
import com.fastaccess.data.dao.ProjectCardModel
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
/**
* Created by Hashemsergani on 11.09.17.
*/
class ColumnCardViewHolder private constructor(item: View, adapter: BaseRecyclerAdapter<*, *, *>, val isOwner: Boolean)
: BaseViewHolder<ProjectCardModel>(item, adapter) {
@BindView(R.id.title) lateinit var title: TextView
@BindView(R.id.addedBy) lateinit var addedBy: TextView
@BindView(R.id.editCard) lateinit var editCard: View
init {
editCard.setOnClickListener(this)
}
override fun bind(t: ProjectCardModel) {
title.text = t.note
addedBy.text = itemView.context.getString(R.string.card_added_by, t.creator?.login)
editCard.visibility = if (isOwner) View.VISIBLE else View.GONE
}
companion object {
fun newInstance(parent: ViewGroup, adapter: BaseRecyclerAdapter<*, *, *>, isOwner: Boolean): ColumnCardViewHolder {
return ColumnCardViewHolder(getView(parent, R.layout.column_card_row_layout), adapter, isOwner)
}
}
}

View File

@ -4,6 +4,7 @@ import android.support.transition.ChangeBounds
import android.support.transition.TransitionManager
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import butterknife.BindView
import com.fastaccess.R
import com.fastaccess.data.dao.model.Comment
@ -43,6 +44,7 @@ class CommitCommentsViewHolder private constructor(view: View, adapter: BaseRecy
@BindView(R.id.commentMenu) lateinit var commentMenu: ForegroundImageView
@BindView(R.id.comment) lateinit var comment: FontTextView
@BindView(R.id.commentOptions) lateinit var commentOptions: View
@BindView(R.id.owner) lateinit var owner: TextView
override fun onClick(v: View) {
if (v.id == R.id.toggle || v.id == R.id.toggleHolder) {
@ -68,6 +70,12 @@ class CommitCommentsViewHolder private constructor(view: View, adapter: BaseRecy
} else {
comment.text = ""
}
if (t.authorAssociation != null && !"none".equals(t.authorAssociation, ignoreCase = true)) {
owner.text = t.authorAssociation.toLowerCase()
owner.visibility = View.VISIBLE
} else {
owner.visibility = View.GONE
}
if (t.createdAt == t.updatedAt) {
date.text = String.format("%s %s", ParseDateFormat.getTimeAgo(t.updatedAt), itemView
.resources.getString(R.string.edited))

View File

@ -26,6 +26,7 @@ public class CommitLinesViewHolder extends BaseViewHolder<CommitLinesModel> {
@BindView(R.id.textView) AppCompatTextView textView;
@BindView(R.id.leftLinNo) AppCompatTextView leftLinNo;
@BindView(R.id.rightLinNo) AppCompatTextView rightLinNo;
@BindView(R.id.hasComment) View hasComment;
private final int patchAdditionColor;
private final int patchDeletionColor;
private final int patchRefColor;
@ -44,6 +45,7 @@ public class CommitLinesViewHolder extends BaseViewHolder<CommitLinesModel> {
@Override public void bind(@NonNull CommitLinesModel item) {
leftLinNo.setText(item.getLeftLineNo() > 0 ? String.valueOf(item.getLeftLineNo()) : " ");
rightLinNo.setText(item.getRightLineNo() > 0 ? String.valueOf(item.getRightLineNo()) : " ");
hasComment.setVisibility(item.isHasCommentedOn() ? View.VISIBLE : View.GONE);
switch (item.getColor()) {
case CommitLinesModel.ADDITION:
textView.setBackgroundColor(patchAdditionColor);

View File

@ -47,12 +47,17 @@ public class IssueTimelineViewHolder extends BaseViewHolder<TimelineModel> {
avatarLayout.setUrl(issueEventModel.getAssigner().getAvatarUrl(), issueEventModel.getAssigner().getLogin(),
false, LinkParserHelper.isEnterprise(issueEventModel.getUrl()));
} else {
if (issueEventModel.getActor() != null) {
avatarLayout.setUrl(issueEventModel.getActor().getAvatarUrl(), issueEventModel.getActor().getLogin(),
false, LinkParserHelper.isEnterprise(issueEventModel.getUrl()));
} else if (issueEventModel.getAuthor() != null) {
avatarLayout.setUrl(issueEventModel.getAuthor().getAvatarUrl(), issueEventModel.getAuthor().getLogin(),
false, LinkParserHelper.isEnterprise(issueEventModel.getUrl()));
if (event != IssueEventType.committed) {
avatarLayout.setVisibility(View.VISIBLE);
if (issueEventModel.getActor() != null) {
avatarLayout.setUrl(issueEventModel.getActor().getAvatarUrl(), issueEventModel.getActor().getLogin(),
false, LinkParserHelper.isEnterprise(issueEventModel.getUrl()));
} else if (issueEventModel.getAuthor() != null) {
avatarLayout.setUrl(issueEventModel.getAuthor().getAvatarUrl(), issueEventModel.getAuthor().getLogin(),
false, LinkParserHelper.isEnterprise(issueEventModel.getUrl()));
}
} else {
avatarLayout.setVisibility(View.GONE);
}
}
if (event != null) {

View File

@ -8,7 +8,7 @@ import com.fastaccess.R
import com.fastaccess.ui.widgets.FontTextView
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
import pr.GetPinnedReposQuery
import github.GetPinnedReposQuery
import java.text.NumberFormat
/**

View File

@ -0,0 +1,38 @@
package com.fastaccess.ui.adapter.viewholder
import android.view.View
import android.view.ViewGroup
import butterknife.BindView
import com.fastaccess.R
import com.fastaccess.helper.ParseDateFormat
import com.fastaccess.ui.widgets.FontTextView
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
import github.RepoProjectsOpenQuery
/**
* Created by kosh on 09/09/2017.
*/
class ProjectViewHolder(view: View, adapter: BaseRecyclerAdapter<*, *, *>) : BaseViewHolder<RepoProjectsOpenQuery.Node>(view, adapter) {
@BindView(R.id.description) lateinit var description: FontTextView
@BindView(R.id.title) lateinit var title: FontTextView
@BindView(R.id.date) lateinit var date: FontTextView
override fun bind(t: RepoProjectsOpenQuery.Node) {
title.text = t.name()
if (t.body().isNullOrBlank()) {
description.visibility = View.GONE
} else {
description.visibility = View.VISIBLE
description.text = t.body()
}
date.text = ParseDateFormat.getTimeAgo(t.createdAt().toString())
}
companion object {
fun newInstance(parent: ViewGroup, adapter: BaseRecyclerAdapter<*, *, *>): ProjectViewHolder {
return ProjectViewHolder(getView(parent, R.layout.feeds_row_no_image_item), adapter)
}
}
}

View File

@ -21,8 +21,8 @@ import com.fastaccess.ui.widgets.SpannableBuilder
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
import com.zzhoujay.markdown.style.CodeSpan
import pr.PullRequestTimelineQuery
import pr.type.StatusState
import github.PullRequestTimelineQuery
import github.type.StatusState
/**
* Created by kosh on 03/08/2017.

View File

@ -30,8 +30,8 @@ import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder;
import java.util.List;
import butterknife.BindView;
import pr.PullRequestTimelineQuery;
import pr.type.ReactionContent;
import github.PullRequestTimelineQuery;
import github.type.ReactionContent;
/**
* Created by Kosh on 11 Nov 2016, 2:08 PM

View File

@ -11,6 +11,7 @@ import com.fastaccess.R;
import com.fastaccess.data.dao.PullRequestStatusModel;
import com.fastaccess.data.dao.types.StatusStateType;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.Logger;
import com.fastaccess.provider.scheme.SchemeParser;
import com.fastaccess.ui.widgets.FontTextView;
import com.fastaccess.ui.widgets.ForegroundImageView;
@ -44,12 +45,20 @@ public class PullStatusViewHolder extends BaseViewHolder<PullRequestStatusModel>
}
@Override public void bind(@NonNull PullRequestStatusModel pullRequestStatusModel) {
Logger.e(pullRequestStatusModel.getState(), pullRequestStatusModel.isMergable());
if (pullRequestStatusModel.getState() != null) {
StatusStateType stateType = pullRequestStatusModel.getState();
stateImage.setImageResource(stateType.getDrawableRes());
if (stateType == StatusStateType.failure) {
stateImage.tintDrawableColor(red);
status.setText(R.string.checks_failed);
if (pullRequestStatusModel.isMergable()) {
status.setText(R.string.checks_failed);
} else {
status.setText(SpannableBuilder.builder()
.append(status.getResources().getString(R.string.checks_failed))
.append("\n")
.append(status.getResources().getString(R.string.can_not_merge_pr)));
}
} else if (stateType == StatusStateType.pending) {
if (pullRequestStatusModel.isMergable()) {
stateImage.setImageResource(R.drawable.ic_check_small);
@ -72,16 +81,14 @@ public class PullStatusViewHolder extends BaseViewHolder<PullRequestStatusModel>
if (pullRequestStatusModel.getStatuses() != null && !pullRequestStatusModel.getStatuses().isEmpty()) {
SpannableBuilder builder = SpannableBuilder.builder();
Stream.of(pullRequestStatusModel.getStatuses())
.filter(statusesModel -> statusesModel.getState() != null)
.filter(statusesModel -> statusesModel != null && statusesModel.getState() != null && statusesModel.getTargetUrl() != null)
.forEach(statusesModel -> {
builder.append(ContextCompat.getDrawable(statuses.getContext(), statusesModel.getState().getDrawableRes()));
if (!InputHelper.isEmpty(statusesModel.getTargetUrl())) {
builder.append(ContextCompat.getDrawable(statuses.getContext(), statusesModel.getState().getDrawableRes()));
builder.append(" ")
.append(statusesModel.getContext() != null ? statusesModel.getContext() + " " : "")
.url(statusesModel.getDescription(), v -> SchemeParser.launchUri(v.getContext(), statusesModel.getTargetUrl()))
.append("\n");
} else {
builder.append("\n");
}
});
if (!InputHelper.isEmpty(builder)) {

View File

@ -108,18 +108,23 @@ public class ReviewCommentsViewHolder extends BaseViewHolder<ReviewCommentModel>
avatarView.setUrl(commentModel.getUser().getAvatarUrl(), commentModel.getUser().getLogin(), commentModel.getUser()
.isOrganizationType(), LinkParserHelper.isEnterprise(commentModel.getHtmlUrl()));
name.setText(commentModel.getUser().getLogin());
boolean isRepoOwner = TextUtils.equals(commentModel.getUser().getLogin(), repoOwner);
if (isRepoOwner) {
if (commentModel.getAuthorAssociation() != null && !"none".equalsIgnoreCase(commentModel.getAuthorAssociation())) {
owner.setText(commentModel.getAuthorAssociation().toLowerCase());
owner.setVisibility(View.VISIBLE);
owner.setText(R.string.owner);
} else {
boolean isPoster = TextUtils.equals(commentModel.getUser().getLogin(), poster);
if (isPoster) {
boolean isRepoOwner = TextUtils.equals(commentModel.getUser().getLogin(), repoOwner);
if (isRepoOwner) {
owner.setVisibility(View.VISIBLE);
owner.setText(R.string.original_poster);
owner.setText(R.string.owner);
} else {
owner.setText(null);
owner.setVisibility(View.GONE);
boolean isPoster = TextUtils.equals(commentModel.getUser().getLogin(), poster);
if (isPoster) {
owner.setVisibility(View.VISIBLE);
owner.setText(R.string.original_poster);
} else {
owner.setText(null);
owner.setVisibility(View.GONE);
}
}
}
}

View File

@ -21,7 +21,8 @@ import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
class ReviewsViewHolder private constructor(itemView: View,
adapter: BaseRecyclerAdapter<*, *, *>?,
val viewGroup: ViewGroup) : BaseViewHolder<TimelineModel>(itemView, adapter) {
val viewGroup: ViewGroup)
: BaseViewHolder<TimelineModel>(itemView, adapter) {
@BindView(R.id.stateImage) lateinit var stateImage: ForegroundImageView
@BindView(R.id.avatarLayout) lateinit var avatarLayout: AvatarLayout
@ -42,7 +43,8 @@ class ReviewsViewHolder private constructor(itemView: View,
it.user.login
} else {
""
}).append(" ${if (model.event == IssueEventType.reviewed) "reviewed" else "requested changes"} ").append(ParseDateFormat.getTimeAgo(it.submittedAt))
}).append(" ${if (model.event == IssueEventType.reviewed) "reviewed" else "requested changes"} ")
.append(ParseDateFormat.getTimeAgo(it.submittedAt))
if (!it.bodyHtml.isNullOrBlank()) {
HtmlHelper.htmlIntoTextView(body, it.bodyHtml, viewGroup.width)
body.visibility = View.VISIBLE

View File

@ -120,18 +120,23 @@ public class TimelineCommentsViewHolder extends BaseViewHolder<TimelineModel> {
avatar.setUrl(commentsModel.getUser().getAvatarUrl(), commentsModel.getUser().getLogin(),
false, LinkParserHelper.isEnterprise(commentsModel.getHtmlUrl()));
name.setText(commentsModel.getUser() != null ? commentsModel.getUser().getLogin() : "Anonymous");
boolean isRepoOwner = TextUtils.equals(commentsModel.getUser().getLogin(), repoOwner);
if (isRepoOwner) {
if (commentsModel.getAuthorAssociation() != null && !"none".equalsIgnoreCase(commentsModel.getAuthorAssociation())) {
owner.setText(commentsModel.getAuthorAssociation().toLowerCase());
owner.setVisibility(View.VISIBLE);
owner.setText(R.string.owner);
} else {
boolean isPoster = TextUtils.equals(commentsModel.getUser().getLogin(), poster);
if (isPoster) {
boolean isRepoOwner = TextUtils.equals(commentsModel.getUser().getLogin(), repoOwner);
if (isRepoOwner) {
owner.setVisibility(View.VISIBLE);
owner.setText(R.string.original_poster);
owner.setText(R.string.owner);
} else {
owner.setText(null);
owner.setVisibility(View.GONE);
boolean isPoster = TextUtils.equals(commentsModel.getUser().getLogin(), poster);
if (isPoster) {
owner.setVisibility(View.VISIBLE);
owner.setText(R.string.original_poster);
} else {
owner.setText(null);
owner.setVisibility(View.GONE);
}
}
}
} else {

View File

@ -19,6 +19,7 @@ import com.evernote.android.state.StateSaver;
import com.fastaccess.R;
import com.fastaccess.helper.AnimHelper;
import com.fastaccess.helper.AppHelper;
import com.fastaccess.helper.PrefGetter;
import com.fastaccess.ui.base.mvp.BaseMvp;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
@ -70,12 +71,17 @@ public abstract class BaseDialogFragment<V extends BaseMvp.FAView, P extends Bas
}
@Override public void dismiss() {
AnimHelper.dismissDialog(this, getResources().getInteger(android.R.integer.config_shortAnimTime), new AnimatorListenerAdapter() {
@Override public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
BaseDialogFragment.super.dismiss();
}
});
if (PrefGetter.isAppAnimationDisabled()) {
super.dismiss();
} else {
AnimHelper.dismissDialog(this, getResources().getInteger(android.R.integer.config_shortAnimTime),
new AnimatorListenerAdapter() {
@Override public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
BaseDialogFragment.super.dismiss();
}
});
}
}
@SuppressLint("RestrictedApi") @Nullable @Override
@ -92,8 +98,10 @@ public abstract class BaseDialogFragment<V extends BaseMvp.FAView, P extends Bas
@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) {
final Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setOnShowListener(dialogInterface -> AnimHelper.revealDialog(dialog,
getResources().getInteger(android.R.integer.config_longAnimTime)));
if (!PrefGetter.isAppAnimationDisabled()) {
dialog.setOnShowListener(dialogInterface -> AnimHelper.revealDialog(dialog,
getResources().getInteger(android.R.integer.config_longAnimTime)));
}
return dialog;
}
@ -134,10 +142,6 @@ public abstract class BaseDialogFragment<V extends BaseMvp.FAView, P extends Bas
}
@Override public void onDialogDismissed() {
}
@Override public void onRequireLogin() {
callback.onRequireLogin();
}
@ -161,6 +165,10 @@ public abstract class BaseDialogFragment<V extends BaseMvp.FAView, P extends Bas
@Override public void onScrollTop(int index) {}
@Override public void onDialogDismissed() {
}
@Override public boolean isEnterprise() {
return callback != null && callback.isEnterprise();
}

View File

@ -11,7 +11,6 @@ import android.widget.TextView
import com.fastaccess.R
import com.fastaccess.data.dao.model.Login
import com.fastaccess.data.dao.model.PinnedRepos
import com.fastaccess.helper.Logger
import com.fastaccess.helper.PrefGetter
import com.fastaccess.helper.RxHelper
import com.fastaccess.provider.scheme.SchemeParser
@ -24,6 +23,7 @@ import com.fastaccess.ui.modules.main.MainActivity
import com.fastaccess.ui.modules.main.premium.PremiumActivity
import com.fastaccess.ui.modules.notification.NotificationActivity
import com.fastaccess.ui.modules.pinned.PinnedReposActivity
import com.fastaccess.ui.modules.repos.issues.create.CreateIssueActivity
import com.fastaccess.ui.modules.trending.TrendingActivity
import com.fastaccess.ui.modules.user.UserPagerActivity
import com.fastaccess.ui.widgets.AvatarLayout
@ -180,6 +180,7 @@ class MainNavDrawer(val view: BaseActivity<*, *>, private val extraNav: Navigati
item.itemId == R.id.orgs -> view.onOpenOrgsDialog()
item.itemId == R.id.notifications -> view.startActivity(Intent(view, NotificationActivity::class.java))
item.itemId == R.id.trending -> view.startActivity(Intent(view, TrendingActivity::class.java))
item.itemId == R.id.reportBug -> view.startActivity(CreateIssueActivity.startForResult(view))
}
}
}, 250)

View File

@ -146,7 +146,7 @@ public class FastHubAboutActivity extends MaterialAboutActivity {
.addItem(new MaterialAboutActionItem.Builder()
.text(R.string.join_slack)
.icon(ContextCompat.getDrawable(context, R.drawable.ic_slack))
.setOnClickAction(() -> ActivityHelper.startCustomTab(this, "http://rebrand.ly/fasthub-slack"))
.setOnClickAction(() -> ActivityHelper.startCustomTab(this, "http://rebrand.ly/fasthub"))
.build())
.addItem(new MaterialAboutActionItem.Builder()
.text(R.string.open_source_libs)

View File

@ -102,7 +102,13 @@ public class CodeViewerActivity extends BaseActivity {
@Override public boolean onOptionsItemSelected(MenuItem item) {
if (InputHelper.isEmpty(url)) return super.onOptionsItemSelected(item);
if (item.getItemId() == R.id.download) {
if (item.getItemId() == R.id.viewAsCode) {
ViewerFragment viewerFragment = (ViewerFragment) AppHelper.getFragmentByTag(getSupportFragmentManager(), ViewerFragment.TAG);
if (viewerFragment != null) {
viewerFragment.onViewAsCode();
}
return true;
} else if (item.getItemId() == R.id.download) {
if (ActivityHelper.checkAndRequestReadWritePermission(this)) {
RestProvider.downloadFile(this, url);
}

View File

@ -23,10 +23,10 @@ import com.fastaccess.data.dao.EditReviewCommentModel
import com.fastaccess.data.dao.model.Comment
import com.fastaccess.helper.*
import com.fastaccess.provider.emoji.Emoji
import com.fastaccess.provider.markdown.CachedComments
import com.fastaccess.provider.markdown.MarkDownProvider
import com.fastaccess.ui.base.BaseActivity
import com.fastaccess.ui.widgets.FontTextView
import com.fastaccess.ui.widgets.dialog.MessageDialogView
import com.fastaccess.ui.widgets.markdown.MarkDownLayout
import com.fastaccess.ui.widgets.markdown.MarkdownEditText
import java.util.*
@ -51,21 +51,13 @@ class EditorActivity : BaseActivity<EditorMvp.View, EditorPresenter>(), EditorMv
@BindView(R.id.parentView) lateinit var parentView: View
@BindView(R.id.autocomplete) lateinit var mention: ListView
@State
@BundleConstant.ExtraType
var extraType: String? = null
@State
var itemId: String? = null
@State
var login: String? = null
@State
var issueNumber: Int = 0
@State
var commentId: Long = 0
@State
var sha: String? = null
@State
var reviewComment: EditReviewCommentModel? = null
@State @BundleConstant.ExtraType var extraType: String? = null
@State var itemId: String? = null
@State var login: String? = null
@State var issueNumber: Int = 0
@State var commentId: Long = 0
@State var sha: String? = null
@State var reviewComment: EditReviewCommentModel? = null
override fun layout(): Int = R.layout.editor_layout
@ -172,6 +164,15 @@ class EditorActivity : BaseActivity<EditorMvp.View, EditorPresenter>(), EditorMv
override fun onBackPressed() {
if (!InputHelper.isEmpty(editText)) {
ViewHelper.hideKeyboard(editText)
MessageDialogView.newInstance(getString(R.string.close), getString(R.string.unsaved_data_warning),
Bundler.start()
.put("primary_extra", getString(R.string.discard))
.put("secondary_extra", getString(R.string.cancel))
.put(BundleConstant.EXTRA, true)
.end())
.show(supportFragmentManager, MessageDialogView.TAG)
return
}
super.onBackPressed()
}
@ -184,12 +185,7 @@ class EditorActivity : BaseActivity<EditorMvp.View, EditorPresenter>(), EditorMv
}
override fun onAppendLink(title: String?, link: String?, isLink: Boolean) {
if (isLink) {
MarkDownProvider.addLink(editText, InputHelper.toString(title), InputHelper.toString(link))
} else {
editText.setText(String.format("%s\n", editText.text))
MarkDownProvider.addPhoto(editText, InputHelper.toString(title), InputHelper.toString(link))
}
markDownLayout.onAppendLink(title, link, isLink)
}
override fun getEditText(): EditText = editText
@ -220,12 +216,12 @@ class EditorActivity : BaseActivity<EditorMvp.View, EditorPresenter>(), EditorMv
commentId = bundle.getLong(BundleConstant.EXTRA_FOUR)
val textToUpdate = bundle.getString(BundleConstant.EXTRA)
if (!InputHelper.isEmpty(textToUpdate)) {
editText.setText(String.format("%s ", textToUpdate))
editText.setText(String.format("%s", textToUpdate))
editText.setSelection(InputHelper.toString(editText).length)
}
if (bundle.getString("message", "").isEmpty())
if (bundle.getString("message", "").isBlank()) {
replyQuote.visibility = GONE
else {
} else {
MarkDownProvider.setMdText(quote, bundle.getString("message", ""))
}
participants = bundle.getStringArrayList("participants")

View File

@ -93,7 +93,7 @@ class EditorPresenter : BasePresenter<EditorMvp.View>(), EditorMvp.Presenter {
}
private fun onEditReviewComment(reviewComment: EditReviewCommentModel, savedText: CharSequence, repoId: String,
login: String, issueNumber: Int, id: Long) {
login: String, @Suppress("UNUSED_PARAMETER") issueNumber: Int, id: Long) {
if (!InputHelper.isEmpty(savedText)) {
val requestModel = CommentRequestModel()
requestModel.body = savedText.toString()

View File

@ -18,30 +18,36 @@ import com.fastaccess.helper.Bundler
import com.fastaccess.helper.InputHelper
import com.fastaccess.helper.ViewHelper
import com.fastaccess.provider.emoji.Emoji
import com.fastaccess.provider.timeline.CommentsHelper
import com.fastaccess.ui.base.BaseFragment
import com.fastaccess.ui.base.mvp.BaseMvp
import com.fastaccess.ui.base.mvp.presenter.BasePresenter
import com.fastaccess.ui.modules.editor.EditorActivity
import com.fastaccess.ui.modules.editor.emoji.EmojiMvp
import com.fastaccess.ui.modules.editor.popup.EditorLinkImageMvp
import com.fastaccess.ui.widgets.markdown.MarkDownLayout
import com.fastaccess.ui.widgets.markdown.MarkdownEditText
import net.yslibrary.android.keyboardvisibilityevent.KeyboardVisibilityEvent
import net.yslibrary.android.keyboardvisibilityevent.Unregistrar
/**
* Created by kosh on 21/08/2017.
*/
class CommentEditorFragment : BaseFragment<BaseMvp.FAView, BasePresenter<BaseMvp.FAView>>(), MarkDownLayout.MarkdownListener,
EmojiMvp.EmojiCallback {
EmojiMvp.EmojiCallback, EditorLinkImageMvp.EditorLinkCallback {
@BindView(R.id.commentBox) lateinit var commentBox: View
@BindView(R.id.markdDownLayout) lateinit var markdDownLayout: MarkDownLayout
@BindView(R.id.commentText) lateinit var commentText: MarkdownEditText
@BindView(R.id.markdownBtnHolder) lateinit var markdownBtnHolder: View
@BindView(R.id.sendComment) lateinit var sendComment: View
@BindView(R.id.toggleButtons) lateinit var toggleButtons: View
private var commentListener: CommentListener? = null
private var keyboardListener: Unregistrar? = null
@OnClick(R.id.sendComment) internal fun onComment() {
if (!InputHelper.isEmpty(getEditText())) {
commentListener?.onSendActionClicked(InputHelper.toString(getEditText()), arguments?.getBundle(BundleConstant.ITEM))
getEditText().setText("")
ViewHelper.hideKeyboard(getEditText())
arguments = null
}
@ -52,6 +58,7 @@ class CommentEditorFragment : BaseFragment<BaseMvp.FAView, BasePresenter<BaseMvp
intent.putExtras(Bundler.start()
.put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraType.FOR_RESULT_EXTRA)
.put(BundleConstant.EXTRA, getEditText().text.toString())
.putStringArrayList("participants", commentListener?.getNamesToTag())
.end())
startActivityForResult(intent, BundleConstant.REQUEST_CODE)
}
@ -81,12 +88,32 @@ class CommentEditorFragment : BaseFragment<BaseMvp.FAView, BasePresenter<BaseMvp
override fun fragmentLayout(): Int = R.layout.comment_box_layout
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
arguments?.let {
val hideSendButton = it.getBoolean(BundleConstant.YES_NO_EXTRA)
if (hideSendButton) {
sendComment.visibility = View.GONE
}
}
markdDownLayout.markdownListener = this
if (savedInstanceState == null) {
commentText.setText(arguments?.getBundle(BundleConstant.ITEM)?.getString(BundleConstant.EXTRA))
}
}
override fun onStart() {
super.onStart()
keyboardListener = KeyboardVisibilityEvent.registerEventListener(activity, {
TransitionManager.beginDelayedTransition((view as ViewGroup?)!!)
toggleButtons.isActivated = it
markdownBtnHolder.visibility = if (!it) View.GONE else View.VISIBLE
})
}
override fun onStop() {
keyboardListener?.unregister()
super.onStop()
}
override fun getEditText(): EditText = commentText
override fun fragmentManager(): FragmentManager = childFragmentManager
@ -113,12 +140,6 @@ class CommentEditorFragment : BaseFragment<BaseMvp.FAView, BasePresenter<BaseMvp
getEditText().setSelection(getEditText().text.length)
}
interface CommentListener {
fun onCreateComment(text: String, bundle: Bundle?) {}
fun onSendActionClicked(text: String, bundle: Bundle?)
fun onTagUser(username: String)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
@ -130,6 +151,18 @@ class CommentEditorFragment : BaseFragment<BaseMvp.FAView, BasePresenter<BaseMvp
}
}
override fun onAppendLink(title: String?, link: String?, isLink: Boolean) {
markdDownLayout.onAppendLink(title, link, isLink)
}
interface CommentListener {
fun onCreateComment(text: String, bundle: Bundle?) {}
fun onSendActionClicked(text: String, bundle: Bundle?)
fun onTagUser(username: String)
fun onClearEditText()
fun getNamesToTag(): ArrayList<String>?
}
companion object {
fun newInstance(bundle: Bundle?): CommentEditorFragment {
val fragment = CommentEditorFragment()

View File

@ -49,7 +49,9 @@ public class EditorLinkImageDialogFragment extends BaseDialogFragment<EditorLink
@Override public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof EditorLinkImageMvp.EditorLinkCallback) {
if (getParentFragment() instanceof EditorLinkImageMvp.EditorLinkCallback) {
callback = (EditorLinkImageMvp.EditorLinkCallback) getParentFragment();
} else if (context instanceof EditorLinkImageMvp.EditorLinkCallback) {
callback = (EditorLinkImageMvp.EditorLinkCallback) context;
}
}
@ -62,7 +64,7 @@ public class EditorLinkImageDialogFragment extends BaseDialogFragment<EditorLink
@Override public void onUploaded(@Nullable String title, @Nullable String link) {
hideProgress();
if (callback != null) {
callback.onAppendLink(title, link, isLink());
callback.onAppendLink(title, link != null ? link.replace("http:", "https:") : null, isLink());
}
dismiss();
}

View File

@ -28,7 +28,7 @@ public class EditorLinkImagePresenter extends BasePresenter<EditorLinkImageMvp.V
return;
}
sendToView(view -> view.onUploaded(null, null));
});
}, false);
} else {
if (getView() != null) getView().onUploaded(null, null);
}

View File

@ -185,7 +185,11 @@ public class FeedsPresenter extends BasePresenter<FeedsMvp.View> implements Feed
.collect(Collectors.toCollection(ArrayList::new)));
}
} else {
onItemClick(position, v, item);
Repo repo = item.getRepo();
if (repo != null) {
NameParser parser = new NameParser(repo.getUrl());
RepoPagerActivity.startRepoPager(v.getContext(), parser);
}
}
}
}

View File

@ -10,17 +10,15 @@ import android.view.View;
import com.evernote.android.state.State;
import com.fastaccess.R;
import com.fastaccess.data.dao.PullsIssuesParser;
import com.fastaccess.data.dao.model.Issue;
import com.fastaccess.data.dao.types.IssueState;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.provider.rest.loadmore.OnLoadMore;
import com.fastaccess.provider.scheme.SchemeParser;
import com.fastaccess.ui.adapter.IssuesAdapter;
import com.fastaccess.ui.base.BaseFragment;
import com.fastaccess.ui.modules.filter.issues.FilterIssuesActivityMvp;
import com.fastaccess.ui.modules.repos.extras.popup.IssuePopupFragment;
import com.fastaccess.ui.modules.repos.issues.issue.details.IssuePagerActivity;
import com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.PullRequestPagerActivity;
import com.fastaccess.ui.widgets.StateLayout;
import com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView;
import com.fastaccess.ui.widgets.recyclerview.scroll.RecyclerViewFastScroller;
@ -132,19 +130,7 @@ public class FilterIssueFragment extends BaseFragment<FilterIssuesMvp.View, Filt
}
@Override public void onItemClicked(@NonNull Issue item) {
PullsIssuesParser parser;
if (!isIssue) {
parser = PullsIssuesParser.getForPullRequest(item.getHtmlUrl());
} else {
parser = PullsIssuesParser.getForIssue(item.getHtmlUrl());
}
if (parser != null) {
if (isIssue) {
startActivity(IssuePagerActivity.createIntent(getContext(), parser.getRepoId(), parser.getLogin(), parser.getNumber(), true));
} else {
startActivity(PullRequestPagerActivity.createIntent(getContext(), parser.getRepoId(), parser.getLogin(), parser.getNumber(), true));
}
}
SchemeParser.launchUri(getContext(), item.getHtmlUrl());
}
@Override protected int fragmentLayout() {

View File

@ -21,7 +21,6 @@ import com.fastaccess.helper.Bundler
import com.fastaccess.helper.InputHelper
import com.fastaccess.helper.ViewHelper
import com.fastaccess.provider.emoji.Emoji
import com.fastaccess.provider.markdown.MarkDownProvider
import com.fastaccess.ui.base.BaseDialogFragment
import com.fastaccess.ui.modules.gists.create.dialog.AddGistMvp.AddGistFileListener
import com.fastaccess.ui.widgets.markdown.MarkDownLayout
@ -61,12 +60,7 @@ class AddGistBottomSheetDialog : BaseDialogFragment<AddGistMvp.View, AddGistPres
override fun providePresenter(): AddGistPresenter = AddGistPresenter()
override fun onAppendLink(title: String?, link: String?, isLink: Boolean) {
if (isLink) {
MarkDownProvider.addLink(editText, InputHelper.toString(title), InputHelper.toString(link))
} else {
editText.setText(String.format("%s\n", editText.text))
MarkDownProvider.addPhoto(editText, InputHelper.toString(title), InputHelper.toString(link))
}
markDownLayout.onAppendLink(title, link, isLink)
}
override fun fragmentLayout(): Int = R.layout.add_gist_file_layout

View File

@ -40,6 +40,8 @@ import com.fastaccess.ui.widgets.ForegroundImageView;
import com.fastaccess.ui.widgets.ViewPagerView;
import com.fastaccess.ui.widgets.dialog.MessageDialogView;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.OnClick;
@ -267,8 +269,7 @@ public class GistActivity extends BaseActivity<GistMvp.View, GistPresenter>
}
@Override public void onSendActionClicked(@NonNull String text, Bundle bundle) {
if (pager == null || pager.getAdapter() == null) return;
GistCommentsFragment view = (GistCommentsFragment) pager.getAdapter().instantiateItem(pager, 1);
GistCommentsFragment view = getGistCommentsFragment();
if (view != null) {
view.onHandleComment(text, bundle);
}
@ -278,6 +279,24 @@ public class GistActivity extends BaseActivity<GistMvp.View, GistPresenter>
commentEditorFragment.onAddUserName(username);
}
@Override public void onCreateComment(String text, Bundle bundle) {
}
@SuppressWarnings("ConstantConditions") @Override public void onClearEditText() {
if (commentEditorFragment != null && commentEditorFragment.commentText != null) commentEditorFragment.commentText.setText(null);
}
@NonNull @Override public ArrayList<String> getNamesToTag() {
GistCommentsFragment view = getGistCommentsFragment();
if (view != null) return view.getNamesToTag();
return new ArrayList<>();
}
@Nullable private GistCommentsFragment getGistCommentsFragment() {
if (pager == null || pager.getAdapter() == null) return null;
return (GistCommentsFragment) pager.getAdapter().instantiateItem(pager, 1);
}
private void hideShowFab() {
if (pager.getCurrentItem() == 1) {
@ -286,8 +305,4 @@ public class GistActivity extends BaseActivity<GistMvp.View, GistPresenter>
getSupportFragmentManager().beginTransaction().hide(commentEditorFragment).commit();
}
}
@Override public void onCreateComment(String text, Bundle bundle) {
}
}

View File

@ -29,6 +29,7 @@ import com.fastaccess.ui.widgets.dialog.MessageDialogView;
import com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView;
import com.fastaccess.ui.widgets.recyclerview.scroll.RecyclerViewFastScroller;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
@ -199,6 +200,11 @@ public class GistCommentsFragment extends BaseFragment<GistCommentsMvp.View, Gis
@Override public void onAddNewComment(@NonNull Comment comment) {
hideProgress();
adapter.addItem(comment);
if (commentsCallback != null) commentsCallback.onClearEditText();
}
@NonNull @Override public ArrayList<String> getNamesToTag() {
return CommentsHelper.getUsers(adapter.getData());
}
@Override public void onDestroyView() {

View File

@ -40,6 +40,8 @@ interface GistCommentsMvp {
void onHandleComment(@NonNull String text, @Nullable Bundle bundle);
void onAddNewComment(@NonNull Comment comment);
@NonNull ArrayList<String> getNamesToTag();
}
interface Presenter extends BaseMvp.FAPresenter,

View File

@ -9,8 +9,10 @@ import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.GravityCompat;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.evernote.android.state.State;
import com.fastaccess.App;
import com.fastaccess.R;
import com.fastaccess.data.dao.model.Login;
import com.fastaccess.data.dao.model.Notification;
@ -109,8 +111,8 @@ public class MainActivity extends BaseActivity<MainMvp.View, MainPresenter> impl
if (isLoggedIn() && Notification.hasUnreadNotifications()) {
ViewHelper.tintDrawable(menu.findItem(R.id.notifications).setIcon(R.drawable.ic_ring).getIcon(), ViewHelper.getAccentColor(this));
} else {
ViewHelper.tintDrawable(menu.findItem(R.id.notifications).setIcon(R.drawable.ic_notifications_none).getIcon(), ViewHelper.getIconColor
(this));
ViewHelper.tintDrawable(menu.findItem(R.id.notifications)
.setIcon(R.drawable.ic_notifications_none).getIcon(), ViewHelper.getIconColor(this));
}
return super.onPrepareOptionsMenu(menu);
}
@ -140,6 +142,11 @@ public class MainActivity extends BaseActivity<MainMvp.View, MainPresenter> impl
invalidateOptionsMenu();
}
@Override public void onUserIsBlackListed() {
Toast.makeText(App.getInstance(), "You are blacklisted, please contact the dev", Toast.LENGTH_LONG).show();
finish();
}
@Shortcut(id = "myIssues", icon = R.drawable.ic_app_shortcut_issues, shortLabelRes = R.string.issues, rank = 2, action = "myIssues")
public void myIssues() {}//do nothing

View File

@ -41,6 +41,8 @@ public interface MainMvp {
void onOpenProfile();
void onInvalidateNotification();
void onUserIsBlackListed();
}
interface Presenter extends BaseMvp.FAPresenter,

View File

@ -10,6 +10,7 @@ import android.support.v4.widget.DrawerLayout;
import com.fastaccess.R;
import com.fastaccess.data.dao.model.Login;
import com.fastaccess.data.dao.model.Notification;
import com.fastaccess.helper.Logger;
import com.fastaccess.helper.ParseDateFormat;
import com.fastaccess.helper.PrefGetter;
import com.fastaccess.helper.RxHelper;
@ -18,6 +19,12 @@ import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
import com.fastaccess.ui.modules.feeds.FeedsFragment;
import com.fastaccess.ui.modules.main.issues.pager.MyIssuesPagerFragment;
import com.fastaccess.ui.modules.main.pullrequests.pager.MyPullsPagerFragment;
import com.github.b3er.rxfirebase.database.RxFirebaseDatabase;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.GenericTypeIndicator;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.Single;
@ -31,6 +38,7 @@ import static com.fastaccess.helper.AppHelper.getFragmentByTag;
public class MainPresenter extends BasePresenter<MainMvp.View> implements MainMvp.Presenter {
MainPresenter() {
checkBlackListed();
setEnterprise(PrefGetter.isEnterprise());
manageDisposable(RxHelper.getObservable(RestProvider.getUserService(isEnterprise()).getUser())
.flatMap(login -> {
@ -47,8 +55,10 @@ public class MainPresenter extends BasePresenter<MainMvp.View> implements MainMv
.flatMap(login -> RxHelper.getObservable(RestProvider.getNotificationService(isEnterprise())
.getNotifications(ParseDateFormat.getLastWeekDate())))
.flatMapSingle(notificationPageable -> {
if (notificationPageable != null) {
if (notificationPageable != null && (notificationPageable.getItems() != null && !notificationPageable.getItems().isEmpty())) {
return Notification.saveAsSingle(notificationPageable.getItems());
} else {
Notification.deleteAll();
}
return Single.just(true);
})
@ -131,4 +141,28 @@ public class MainPresenter extends BasePresenter<MainMvp.View> implements MainMv
}
@Override public void onMenuItemReselect(@IdRes int id, int position, boolean fromUser) {}
private void checkBlackListed() {
manageDisposable(RxHelper.getSingle(RxFirebaseDatabase
.data(FirebaseDatabase.getInstance().getReference().child("black_listed")))
.map(dataSnapshot -> {
boolean exists = false;
Login login = Login.getUser();
Logger.e(dataSnapshot);
if (login != null) {
if (dataSnapshot != null && dataSnapshot.exists()) {
List<String> values = dataSnapshot.getValue(new GenericTypeIndicator<ArrayList<String>>() {});
if (values != null && !values.isEmpty()) {
exists = values.contains(Login.getUser().getLogin());
}
}
}
return exists;
})
.subscribe(exists -> {
if (exists) {
sendToView(MainMvp.View::onUserIsBlackListed);
}
}, Throwable::printStackTrace));
}
}

View File

@ -1,5 +1,6 @@
package com.fastaccess.ui.modules.main.premium
import android.animation.Animator
import android.app.Activity
import android.content.Context
import android.content.Intent
@ -10,6 +11,7 @@ import android.widget.FrameLayout
import butterknife.BindView
import butterknife.OnClick
import butterknife.OnEditorAction
import com.airbnb.lottie.LottieAnimationView
import com.fastaccess.BuildConfig
import com.fastaccess.R
import com.fastaccess.helper.AppHelper
@ -28,6 +30,8 @@ class PremiumActivity : BaseActivity<PremiumMvp.View, PremiumPresenter>(), Premi
@BindView(R.id.editText) lateinit var editText: EditText
@BindView(R.id.viewGroup) lateinit var viewGroup: FrameLayout
@BindView(R.id.progressLayout) lateinit var progressLayout: View
@BindView(R.id.successActivationView) lateinit var successActivationView: LottieAnimationView
@BindView(R.id.successActivationHolder) lateinit var successActivationHolder: View
override fun layout(): Int = R.layout.pro_features_layout
@ -87,11 +91,23 @@ class PremiumActivity : BaseActivity<PremiumMvp.View, PremiumPresenter>(), Premi
}
override fun onSuccessfullyActivated() {
FabricProvider.logPurchase(InputHelper.toString(editText))
PrefGetter.setProItems()
PrefGetter.setEnterpriseItem()
showMessage(R.string.success, R.string.success)
successResult()
hideProgress()
successActivationHolder.visibility = View.VISIBLE
successActivationView.addAnimatorListener(object : Animator.AnimatorListener {
override fun onAnimationRepeat(p0: Animator?) {}
override fun onAnimationEnd(p0: Animator?) {
FabricProvider.logPurchase(InputHelper.toString(editText))
PrefGetter.setProItems()
PrefGetter.setEnterpriseItem()
showMessage(R.string.success, R.string.success)
successResult()
}
override fun onAnimationCancel(p0: Animator?) {}
override fun onAnimationStart(p0: Animator?) {}
})
successActivationView.playAnimation()
}
override fun onNoMatch() {

View File

@ -40,6 +40,7 @@ import com.fastaccess.ui.adapter.ProfilePinnedReposAdapter;
import com.fastaccess.ui.base.BaseFragment;
import com.fastaccess.ui.modules.profile.ProfilePagerMvp;
import com.fastaccess.ui.widgets.AvatarLayout;
import com.fastaccess.ui.widgets.FontButton;
import com.fastaccess.ui.widgets.FontTextView;
import com.fastaccess.ui.widgets.SpannableBuilder;
import com.fastaccess.ui.widgets.contributions.GitHubContributionsView;
@ -51,7 +52,7 @@ import java.util.List;
import butterknife.BindView;
import butterknife.OnClick;
import pr.GetPinnedReposQuery;
import github.GetPinnedReposQuery;
import static android.view.Gravity.TOP;
import static android.view.View.GONE;
@ -78,8 +79,8 @@ public class ProfileOverviewFragment extends BaseFragment<ProfileOverviewMvp.Vie
@BindView(R.id.email) FontTextView email;
@BindView(R.id.link) FontTextView link;
@BindView(R.id.joined) FontTextView joined;
@BindView(R.id.following) FontTextView following;
@BindView(R.id.followers) FontTextView followers;
@BindView(R.id.following) FontButton following;
@BindView(R.id.followers) FontButton followers;
@BindView(R.id.progress) View progress;
@BindView(R.id.followBtn) Button followBtn;
@BindView(R.id.orgsList) DynamicRecyclerView orgsList;
@ -226,12 +227,14 @@ public class ProfileOverviewFragment extends BaseFragment<ProfileOverviewMvp.Vie
}
followers.setText(SpannableBuilder.builder()
.append(getString(R.string.followers))
.append("\n")
.bold(String.valueOf(userModel.getFollowers())));
.append(" (")
.bold(String.valueOf(userModel.getFollowers()))
.append(")"));
following.setText(SpannableBuilder.builder()
.append(getString(R.string.following))
.append("\n")
.bold(String.valueOf(userModel.getFollowing())));
.append(" (")
.bold(String.valueOf(userModel.getFollowing()))
.append(")"));
}
@Override public void invalidateFollowBtn() {
@ -278,6 +281,7 @@ public class ProfileOverviewFragment extends BaseFragment<ProfileOverviewMvp.Vie
}
@Override public void onInitPinnedRepos(@NonNull List<GetPinnedReposQuery.Node> nodes) {
if (pinnedReposTextView == null) return;
if (!nodes.isEmpty()) {
pinnedReposTextView.setVisibility(VISIBLE);
pinnedReposCard.setVisibility(VISIBLE);

View File

@ -13,7 +13,7 @@ import com.fastaccess.ui.widgets.contributions.GitHubContributionsView;
import java.util.ArrayList;
import java.util.List;
import pr.GetPinnedReposQuery;
import github.GetPinnedReposQuery;
/**
* Created by Kosh on 03 Dec 2016, 9:15 AM

View File

@ -8,12 +8,12 @@ import android.text.TextUtils;
import com.apollographql.apollo.ApolloCall;
import com.apollographql.apollo.rx2.Rx2Apollo;
import com.fastaccess.App;
import com.fastaccess.data.dao.model.Login;
import com.fastaccess.data.dao.model.User;
import com.fastaccess.helper.BundleConstant;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.RxHelper;
import com.fastaccess.provider.rest.ApolloProdivder;
import com.fastaccess.provider.rest.RestProvider;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
import com.fastaccess.ui.widgets.contributions.ContributionsDay;
@ -23,8 +23,8 @@ import com.fastaccess.ui.widgets.contributions.GitHubContributionsView;
import java.util.ArrayList;
import java.util.List;
import github.GetPinnedReposQuery;
import io.reactivex.Observable;
import pr.GetPinnedReposQuery;
/**
* Created by Kosh on 03 Dec 2016, 9:16 AM
@ -106,11 +106,11 @@ class ProfileOverviewPresenter extends BasePresenter<ProfileOverviewMvp.View> im
}
@SuppressWarnings("ConstantConditions") private void loadPinnedRepos(@NonNull String login) {
ApolloCall<GetPinnedReposQuery.Data> apolloCall = App.getInstance().getApolloClient()
ApolloCall<GetPinnedReposQuery.Data> apolloCall = ApolloProdivder.INSTANCE.getApollo(isEnterprise())
.query(GetPinnedReposQuery.builder()
.login(login)
.build());
manageObservable(Rx2Apollo.from(apolloCall)
manageDisposable(RxHelper.getObservable(Rx2Apollo.from(apolloCall))
.filter(dataResponse -> !dataResponse.hasErrors())
.flatMap(dataResponse -> {
if (dataResponse.data() != null && dataResponse.data().user() != null) {
@ -121,11 +121,11 @@ class ProfileOverviewPresenter extends BasePresenter<ProfileOverviewMvp.View> im
.map(GetPinnedReposQuery.Edge::node)
.toList()
.toObservable()
.doOnNext(nodes1 -> {
.subscribe(nodes1 -> {
nodes.clear();
nodes.addAll(nodes1);
sendToView(view -> view.onInitPinnedRepos(nodes));
}));
}, Throwable::printStackTrace));
}
@Override public void onWorkOffline(@NonNull String login) {

View File

@ -39,6 +39,7 @@ import com.fastaccess.helper.TypeFaceHelper;
import com.fastaccess.helper.ViewHelper;
import com.fastaccess.provider.colors.ColorsProvider;
import com.fastaccess.provider.scheme.LinkParserHelper;
import com.fastaccess.provider.scheme.SchemeParser;
import com.fastaccess.provider.tasks.git.GithubActionService;
import com.fastaccess.ui.adapter.TopicsAdapter;
import com.fastaccess.ui.base.BaseActivity;
@ -102,6 +103,7 @@ public class RepoPagerActivity extends BaseActivity<RepoPagerMvp.View, RepoPager
@State @RepoPagerMvp.RepoNavigationType int navType;
@State String login;
@State String repoId;
@State int showWhich = -1;
private NumberFormat numberFormat = NumberFormat.getNumberInstance();
private boolean userInteracted;
@ -127,11 +129,17 @@ public class RepoPagerActivity extends BaseActivity<RepoPagerMvp.View, RepoPager
public static Intent createIntent(@NonNull Context context, @NonNull String repoId, @NonNull String login,
@RepoPagerMvp.RepoNavigationType int navType) {
return createIntent(context, repoId, login, navType, -1);
}
public static Intent createIntent(@NonNull Context context, @NonNull String repoId, @NonNull String login,
@RepoPagerMvp.RepoNavigationType int navType, int showWhat) {
Intent intent = new Intent(context, RepoPagerActivity.class);
intent.putExtras(Bundler.start()
.put(BundleConstant.ID, repoId)
.put(BundleConstant.EXTRA_TWO, login)
.put(BundleConstant.EXTRA_TYPE, navType)
.put(BundleConstant.EXTRA_THREE, showWhat)
.end());
return intent;
}
@ -254,13 +262,13 @@ public class RepoPagerActivity extends BaseActivity<RepoPagerMvp.View, RepoPager
@OnLongClick({R.id.forkRepoLayout, R.id.starRepoLayout, R.id.watchRepoLayout}) boolean onLongClick(View view) {
switch (view.getId()) {
case R.id.forkRepoLayout:
RepoMiscDialogFragment.show(getSupportFragmentManager(), getPresenter().login(), getPresenter().repoId(), RepoMiscMVp.FORKS);
RepoMiscDialogFragment.show(getSupportFragmentManager(), login, repoId, RepoMiscMVp.FORKS);
return true;
case R.id.starRepoLayout:
RepoMiscDialogFragment.show(getSupportFragmentManager(), getPresenter().login(), getPresenter().repoId(), RepoMiscMVp.STARS);
RepoMiscDialogFragment.show(getSupportFragmentManager(), login, repoId, RepoMiscMVp.STARS);
return true;
case R.id.watchRepoLayout:
RepoMiscDialogFragment.show(getSupportFragmentManager(), getPresenter().login(), getPresenter().repoId(), RepoMiscMVp.WATCHERS);
RepoMiscDialogFragment.show(getSupportFragmentManager(), login, repoId, RepoMiscMVp.WATCHERS);
return true;
}
return false;
@ -306,8 +314,7 @@ public class RepoPagerActivity extends BaseActivity<RepoPagerMvp.View, RepoPager
repoId = extras.getString(BundleConstant.ID);
login = extras.getString(BundleConstant.EXTRA_TWO);
navType = extras.getInt(BundleConstant.EXTRA_TYPE);
}
if (savedInstanceState == null) {
showWhich = extras.getInt(BundleConstant.EXTRA_THREE);
getPresenter().onUpdatePinnedEntry(repoId, login);
}
getPresenter().onActivityCreate(repoId, login, navType);
@ -348,9 +355,24 @@ public class RepoPagerActivity extends BaseActivity<RepoPagerMvp.View, RepoPager
if (getPresenter().getRepo() == null) {
return;
}
switch (showWhich) {
case 1:
onLongClick(watchRepoLayout);
break;
case 2:
onLongClick(starRepoLayout);
break;
case 3:
onLongClick(forkRepoLayout);
break;
}
showWhich = -1;
setTaskName(getPresenter().getRepo().getFullName());
bottomNavigation.setOnMenuItemClickListener(getPresenter());
Repo repoModel = getPresenter().getRepo();
if (repoModel.isHasProjects()) {
bottomNavigation.inflateMenu(R.menu.repo_with_project_bottom_nav_menu);
}
bottomNavigation.setOnMenuItemClickListener(getPresenter());
if (repoModel.getTopics() != null && !repoModel.getTopics().isEmpty()) {
tagsIcon.setVisibility(View.VISIBLE);
topicsList.setAdapter(new TopicsAdapter(repoModel.getTopics()));
@ -468,6 +490,16 @@ public class RepoPagerActivity extends BaseActivity<RepoPagerMvp.View, RepoPager
UserPagerActivity.startActivity(this, Login.getUser().getLogin(), false, PrefGetter.isEnterprise(), -1);
}
@Override public void onScrolled(boolean isUp) {
if (fab != null) {
if (isUp) {
fab.hide();
} else {
fab.show();
}
}
}
@Override public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.repo_menu, menu);
return super.onCreateOptionsMenu(menu);
@ -501,7 +533,7 @@ public class RepoPagerActivity extends BaseActivity<RepoPagerMvp.View, RepoPager
} else if (item.getItemId() == R.id.originalRepo) {
if (getPresenter().getRepo() != null && getPresenter().getRepo().getParent() != null) {
Repo parent = getPresenter().getRepo().getParent();
RepoPagerActivity.startRepoPager(this, new NameParser(parent.getHtmlUrl()));
SchemeParser.launchUri(this, parent.getHtmlUrl());
}
return true;
} else if (item.getItemId() == R.id.deleteRepo) {

View File

@ -24,12 +24,14 @@ public interface RepoPagerMvp {
int CODE = 0;
int ISSUES = 1;
int PULL_REQUEST = 2;
int PROFILE = 3;
int PROJECTS = 3;
int PROFILE = 4;
@IntDef({
CODE,
ISSUES,
PULL_REQUEST,
PROJECTS,
PROFILE
})
@Retention(RetentionPolicy.SOURCE) @interface RepoNavigationType {}
@ -63,12 +65,13 @@ public interface RepoPagerMvp {
void onChangeForkCount(boolean isForked);
boolean hasUserInteractedWithView();
void disableIssueTab();
void openUserProfile();
void onScrolled(boolean isUp);
}
interface Presenter extends BaseMvp.FAPresenter, BottomNavigation.OnMenuItemSelectionListener {

View File

@ -18,6 +18,7 @@ import com.fastaccess.provider.rest.RestProvider;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
import com.fastaccess.ui.modules.repos.code.RepoCodePagerFragment;
import com.fastaccess.ui.modules.repos.issues.RepoIssuesPagerFragment;
import com.fastaccess.ui.modules.repos.projects.RepoProjectsFragmentPager;
import com.fastaccess.ui.modules.repos.pull_requests.RepoPullRequestPagerFragment;
import static com.fastaccess.helper.ActivityHelper.getVisibleFragment;
@ -185,6 +186,8 @@ class RepoPagerPresenter extends BasePresenter<RepoPagerMvp.View> implements Rep
AppHelper.getFragmentByTag(fragmentManager, RepoIssuesPagerFragment.TAG);
RepoPullRequestPagerFragment pullRequestPagerView = (RepoPullRequestPagerFragment)
AppHelper.getFragmentByTag(fragmentManager, RepoPullRequestPagerFragment.TAG);
RepoProjectsFragmentPager projectsFragmentPager = (RepoProjectsFragmentPager) AppHelper.getFragmentByTag(fragmentManager,
RepoProjectsFragmentPager.Companion.getTAG());
if (getRepo() == null) {
sendToView(RepoPagerMvp.View::onFinishActivity);
return;
@ -219,6 +222,13 @@ class RepoPagerPresenter extends BasePresenter<RepoPagerMvp.View> implements Rep
onShowHideFragment(fragmentManager, pullRequestPagerView, currentVisible);
}
break;
case RepoPagerMvp.PROJECTS:
if (projectsFragmentPager == null) {
onAddAndHide(fragmentManager, RepoProjectsFragmentPager.Companion.newInstance(repoId(), login()), currentVisible);
} else {
onShowHideFragment(fragmentManager, projectsFragmentPager, currentVisible);
}
break;
}
}

View File

@ -43,12 +43,22 @@ public class RepoCommitsFragment extends BaseFragment<RepoCommitsMvp.View, RepoC
private RepoPagerMvp.TabsBadgeListener tabsBadgeListener;
public static RepoCommitsFragment newInstance(@NonNull String repoId, @NonNull String login, @NonNull String branch) {
RepoCommitsFragment view = new RepoCommitsFragment();
view.setArguments(Bundler.start()
return newInstance(repoId, login, branch, null);
}
public static RepoCommitsFragment newInstance(@NonNull String repoId, @NonNull String login, @NonNull String branch,
@Nullable String path) {
return newInstance(Bundler.start()
.put(BundleConstant.ID, repoId)
.put(BundleConstant.EXTRA, login)
.put(BundleConstant.EXTRA_TWO, branch)
.put(BundleConstant.EXTRA_THREE, path)
.end());
}
public static RepoCommitsFragment newInstance(@NonNull Bundle bundle) {
RepoCommitsFragment view = new RepoCommitsFragment();
view.setArguments(bundle);
return view;
}

Some files were not shown because too many files have changed in this diff Show More