Merge pull request #17 from k0shk0sh/master

applying commits
This commit is contained in:
Felix Naumann 2017-10-09 17:43:51 +02:00 committed by GitHub
commit 7725b2bc4a
160 changed files with 2577 additions and 8544 deletions

3
.gitignore vendored
View File

@ -8,5 +8,4 @@
/app/google-services.json
/app/build/
/app/src/main/res/values/secrets.xml
/app/fastaccess-key
/jobdispatcher/build/
/app/fastaccess-key

View File

@ -18,7 +18,7 @@ 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)
# Features
## Features
- **App**
- Three login types (Basic Auth), (Access Token) or via (OAuth)
- Multiple Accounts
@ -27,13 +27,15 @@ Yet another **open-source** GitHub client app but unlike any other app, FastHub
- Offline-mode
- Markdown and code highlighting support
- Notifications overview and "Mark all as read"
- Search users/orgs, repos, issues/prs & code.
- Search Users/Orgs, Repos, Issues/PRs & Code.
- FastHub & GitHub Pinned Repos
- Trending
- Wiki
- Projects
- **Repositories**
- Browse & Read Wiki
- Edit, Create & Delete files (commit)
- Edit, Create & Delete files (Project Columns Cards)
- Search Repos
- Browse and search Repos
- See your public, private and forked Repos
@ -65,7 +67,7 @@ Yet another **open-source** GitHub client app but unlike any other app, FastHub
- Edit Gist & Gist Files
- React to Commit comments with reactions
- Comment on line number in Files/Code changes.
- **Orgs**
- **Organisations**
- Overview
- Feeds
- Teams & Teams repos
@ -85,7 +87,7 @@ _Ads currently not available._
## Specs / Open-source libraries:
- Minimum **SDK 21**, _but AppCompat is used all the way ;-)_
- **Kotlin** all new modules starting from 2.5.3 will be written in **#Kotlin**.
- [**Kotlin**](https://github.com/JetBrains/kotlin) all new modules starting from 2.5.3 will be written in **#Kotlin**.
- **MVP**-architecture: [**ThirtyInch**](https://github.com/grandcentrix/ThirtyInch) because its ThirtyInch.
- [**RxJava2**](https://github.com/ReactiveX/RxJava) & [**RxAndroid**](https://github.com/ReactiveX/RxAndroid) for Retrofit & background threads
- [**Retrofit**](https://github.com/square/retrofit) for constructing the REST API
@ -100,7 +102,7 @@ _Ads currently not available._
- [**Toasty**](https://github.com/GrenderG/Toasty) for displaying error/success messages
- [**ShapedImageView**](https://github.com/gavinliu/ShapedImageView) for round avatars
- [**Material-About-Library**](https://github.com/daniel-stoneuk/material-about-library) for the about screen
- **Fabric** analytics & crash reporting.
- [**Fabric**](https://fabric.io/kits/android/crashlytics) analytics & crash reporting.
- **Android Support Libraries**, the almighty ;-)
## Contribution
@ -113,6 +115,7 @@ Read the [**contribution guide**](.github/CONTRIBUTING.md) for more detailed inf
<details>
<summary>Thanks for those who contributed to FastHub by adding their language</summary>
<p>- Chinese (Simplified) <a href="https://github.com/devifish">@Devifish</a></p>
<p>- Chinese (Traditional) <a href="https://github.com/maple3142">@maple3142</a></p>
<p>- German <a href="https://github.com/failex234">@failex234</a></p>
@ -126,6 +129,7 @@ Read the [**contribution guide**](.github/CONTRIBUTING.md) for more detailed inf
<p>- Czech <a href="https://github.com/hejsekvojtech">@hejsekvojtech</a></p>
<p>- Spanish <a href="https://github.com/alete89">@alete89</a></p>
<p>- French <a href="https://github.com/ptt-homme">@ptt-homme</a></p>
<p>- Korean <a href="https://github.com/Astro36">@Astro36</a> <a href="https://github.com/cozyplanes">@cozyplanes</a></p>
</details>
## FAQ
@ -137,21 +141,33 @@ Read the [**contribution guide**](.github/CONTRIBUTING.md) for more detailed inf
</details>
<details>
<summary>I tried to login via Access Token & OTP but it does not work?</summary>
<summary>I tried to login via Access Token & OTP but why isn't it working?</summary>
<p>You can't login via Access Token & OTP all together due to the lifetime of the OTP code, you'll be required to login in every few seconds.</p>
</details>
<details>
<summary>Why my Private Repo Wiki does not show up?</summary>
<summary>Why are my Private Repo and Enterprise Wiki not showing up?</summary>
<p>It's due to FastHub scraping GitHub Wiki page & Private Repos require session token that FastHub doesn't have.</p>
</details>
<details>
<summary>I login with Enterprise account but can't interact with anything other than my Enterprise GitHub</summary>
<p>Well, logically, you can't access anything else other than your Enterprise, but FastHub made that possible but can't do much about it,
in most cases since your login credential doesn't exists in GitHub server. But in <b>few</b>
cases your GitHub account Oauth token will do the trick.</p>
<summary>I login with Enterprise account but can't interact with anything other than my Enterprise GitHub.</summary>
<p>Well, logically, you can't access anything else other than your Enterprise, but FastHub made that possible but can't do much about it, in most cases since your login credential doesn't exists in GitHub server. But in <b>few</b> cases your GitHub account Oauth token will do the trick.</p>
</details>
<details>
<summary>Why am I having problems editing Issues/PRs?</summary>
<p>If you are unable to edit an issue in a public organization, please contact your Organization Admin to grant access to FastHub. Alternatively you can login using an Access Token with the correct permissions granted.</p>
</details>
<details>
<summary>I'm having this issue! / I want this and that!</summary>
<p>Head to https://github.com/k0shk0sh/FastHub/issues/new and create new issue for bugs or feature requests. I really encourage you to search before opening a ticket. Any duplicate request will result in it being closed immediately.</p>
</details>
<details>
<summary>How do I get PROMO CODE?</summary>
<p>Please refer to the in-app FAQ for details.</p>
</details>

View File

@ -24,13 +24,13 @@ android {
}
}
compileSdkVersion 26
buildToolsVersion "26.0.1"
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "com.fastaccess.github"
minSdkVersion 21
targetSdkVersion 26
versionCode 420
versionName "4.2.0"
versionCode 441
versionName "4.4.1"
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
@ -167,7 +167,7 @@ dependencies {
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')
implementation 'com.firebase:firebase-jobdispatcher:0.8.2'
compileOnly "org.projectlombok:lombok:${lombokVersion}"
kapt "org.projectlombok:lombok:${lombokVersion}"
kapt "com.evernote:android-state-processor:${state_version}"

View File

@ -213,12 +213,6 @@
android:configChanges="keyboard|orientation|screenSize"
android:theme="@style/ThemeTranslucent"/>
<activity
android:name=".ui.modules.reviews.changes.ReviewChangesActivity"
android:configChanges="keyboard|orientation|screenSize"
android:label="@string/review_changes"
android:theme="@style/ThemeTranslucent"/>
<activity
android:name=".ui.modules.repos.wiki.WikiActivity"
android:label="@string/gollum"
@ -258,6 +252,21 @@
android:value=".ui.modules.repos.RepoPagerActivity"/>
</activity>
<activity
android:name=".ui.modules.profile.org.project.OrgProjectActivity"
android:label="@string/projects"
android:parentActivityName=".ui.modules.user.UserPagerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.modules.user.UserPagerActivity"/>
</activity>
<activity android:name=".ui.modules.main.playstore.PlayStoreWarningActivity"/>
<activity
android:name=".ui.modules.repos.pull_requests.pull_request.details.files.fullscreen.FullScreenFileChangeActivity"
android:configChanges="keyboard|orientation|screenSize"/>
<activity
android:name=".ui.modules.parser.LinksParserActivity"

View File

@ -82,7 +82,7 @@ body kbd {
padding: 3px 5px;
font-size: 11px;
line-height: 10px;
color: #656d78;
color: #fff;
vertical-align: middle;
border: solid 1px #656d78;
border-bottom-color: #bbb;

View File

@ -5,6 +5,11 @@ repository(owner: $owner, name: $name) {
edges {
cursor
}
pageInfo {
hasNextPage
startCursor
endCursor
}
nodes {
name
number
@ -27,6 +32,66 @@ repository(owner: $owner, name: $name) {
edges {
cursor
}
pageInfo {
hasNextPage
startCursor
endCursor
}
nodes {
name
number
body
createdAt
id
viewerCanUpdate
columns(first: 1) {
totalCount
}
databaseId
}
}
}
}
query orgProjectsOpen($owner: String!, $page: String) {
organization(login: $owner) {
projects(first: 30, states: OPEN, after: $page, orderBy: {field: CREATED_AT, direction: DESC}) {
totalCount
edges {
cursor
}
pageInfo {
hasNextPage
startCursor
endCursor
}
nodes {
name
number
body
createdAt
id
viewerCanUpdate
columns(first: 1) {
totalCount
}
databaseId
}
}
}
}
query orgProjectsClosed($owner: String!, $page: String) {
organization(login: $owner) {
projects(first: 30, states: CLOSED, after: $page, orderBy: {field: CREATED_AT, direction: DESC}) {
totalCount
edges {
cursor
}
pageInfo {
hasNextPage
startCursor
endCursor
}
nodes {
name
number

View File

@ -25,9 +25,9 @@ import lombok.Setter;
private CommitFileChanges() {}
public static Observable<CommitFileChanges> constructToObservable(@Nullable List<CommitFileModel> files) {
public static Observable<CommitFileChanges> constructToObservable(@Nullable ArrayList<CommitFileModel> files) {
if (files == null || files.isEmpty()) return Observable.empty();
return Observable.fromIterable(files).map(CommitFileChanges::getCommitFileChanges);
return Observable.fromIterable(construct(files));
}
@NonNull public static List<CommitFileChanges> construct(@Nullable List<CommitFileModel> files) {
@ -66,4 +66,11 @@ import lombok.Setter;
@Override public CommitFileChanges[] newArray(int size) {return new CommitFileChanges[size];}
};
public static boolean canAttachToBundle(CommitFileChanges model) {
Parcel parcel = Parcel.obtain();
model.writeToParcel(parcel, 0);
int size = parcel.dataSize();
return size < 600000;
}
}

View File

@ -3,14 +3,9 @@ package com.fastaccess.data.dao;
import android.os.Parcel;
import android.os.Parcelable;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* Created by Kosh on 01 Jan 2017, 9:00 PM
*/
@Getter @Setter @NoArgsConstructor
public class CommitFileModel implements Parcelable {
private String sha;
@ -72,4 +67,84 @@ public class CommitFileModel implements Parcelable {
", patch='" + patch + '\'' +
'}';
}
public String getSha() {
return sha;
}
public void setSha(String sha) {
this.sha = sha;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public int getAdditions() {
return additions;
}
public void setAdditions(int additions) {
this.additions = additions;
}
public int getDeletions() {
return deletions;
}
public void setDeletions(int deletions) {
this.deletions = deletions;
}
public int getChanges() {
return changes;
}
public void setChanges(int changes) {
this.changes = changes;
}
public String getBlobUrl() {
return blobUrl;
}
public void setBlobUrl(String blobUrl) {
this.blobUrl = blobUrl;
}
public String getRawUrl() {
return rawUrl;
}
public void setRawUrl(String rawUrl) {
this.rawUrl = rawUrl;
}
public String getContentsUrl() {
return contentsUrl;
}
public void setContentsUrl(String contentsUrl) {
this.contentsUrl = contentsUrl;
}
public String getPatch() {
return patch;
}
public void setPatch(String patch) {
this.patch = patch;
}
}

View File

@ -12,8 +12,6 @@ import java.util.List;
import java.util.regex.Matcher;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import static com.fastaccess.ui.widgets.DiffLineSpan.HUNK_TITLE;
@ -21,7 +19,7 @@ import static com.fastaccess.ui.widgets.DiffLineSpan.HUNK_TITLE;
* Created by Kosh on 20 Jun 2017, 7:32 PM
*/
@Getter @Setter @AllArgsConstructor public class CommitLinesModel implements Parcelable {
@AllArgsConstructor public class CommitLinesModel implements Parcelable {
public static final int TRANSPARENT = 0;
public static final int ADDITION = 1;
@ -115,4 +113,60 @@ import static com.fastaccess.ui.widgets.DiffLineSpan.HUNK_TITLE;
@Override public CommitLinesModel[] newArray(int size) {return new CommitLinesModel[size];}
};
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getLeftLineNo() {
return leftLineNo;
}
public void setLeftLineNo(int leftLineNo) {
this.leftLineNo = leftLineNo;
}
public int getRightLineNo() {
return rightLineNo;
}
public void setRightLineNo(int rightLineNo) {
this.rightLineNo = rightLineNo;
}
public boolean isNoNewLine() {
return noNewLine;
}
public void setNoNewLine(boolean noNewLine) {
this.noNewLine = noNewLine;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public boolean isHasCommentedOn() {
return hasCommentedOn;
}
public void setHasCommentedOn(boolean hasCommentedOn) {
this.hasCommentedOn = hasCommentedOn;
}
}

View File

@ -3,6 +3,8 @@ package com.fastaccess.data.dao;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@ -15,17 +17,26 @@ import lombok.Setter;
public class CreateIssueModel implements Parcelable {
private String title;
private String body;
private ArrayList<String> labels;
private ArrayList<String> assignees;
private long milestone;
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.title);
dest.writeString(this.body);
dest.writeStringList(this.labels);
dest.writeStringList(this.assignees);
dest.writeLong(this.milestone);
}
@SuppressWarnings("WeakerAccess") protected CreateIssueModel(Parcel in) {
protected CreateIssueModel(Parcel in) {
this.title = in.readString();
this.body = in.readString();
this.labels = in.createStringArrayList();
this.assignees = in.createStringArrayList();
this.milestone = in.readLong();
}
public static final Creator<CreateIssueModel> CREATOR = new Creator<CreateIssueModel>() {

View File

@ -2,6 +2,7 @@ package com.fastaccess.data.dao;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import com.annimon.stream.Collectors;
@ -239,7 +240,7 @@ import lombok.Setter;
.toList();
}
@NonNull public static List<FragmentPagerAdapterModel> buildForRepoProjects(@NonNull Context context, @NonNull String repoId,
@NonNull public static List<FragmentPagerAdapterModel> buildForRepoProjects(@NonNull Context context, @Nullable String repoId,
@NonNull String login) {
return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.open),
RepoProjectFragment.Companion.newInstance(login, repoId, IssueState.open)),

View File

@ -0,0 +1,56 @@
package com.fastaccess.data.dao;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by Hashemsergani on 03.10.17.
*/
public class ProUsersModel implements Parcelable {
private int count;
private boolean allowed;
private int type;
public int getCount() { return count;}
public void setCount(int count) { this.count = count;}
public boolean isAllowed() { return allowed;}
public void setAllowed(boolean allowed) { this.allowed = allowed;}
public int getType() { return type;}
public void setType(int type) { this.type = type;}
@Override public String toString() {
return "ProUsersModel{" +
", count=" + count +
", allowed=" + allowed +
", type=" + type +
'}';
}
public ProUsersModel() {}
@Override public int describeContents() { return 0; }
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.count);
dest.writeByte(this.allowed ? (byte) 1 : (byte) 0);
dest.writeInt(this.type);
}
protected ProUsersModel(Parcel in) {
this.count = in.readInt();
this.allowed = in.readByte() != 0;
this.type = in.readInt();
}
public static final Creator<ProUsersModel> CREATOR = new Creator<ProUsersModel>() {
@Override public ProUsersModel createFromParcel(Parcel source) {return new ProUsersModel(source);}
@Override public ProUsersModel[] newArray(int size) {return new ProUsersModel[size];}
};
}

View File

@ -19,6 +19,7 @@ import io.requery.Entity;
import io.requery.Key;
import io.requery.Persistable;
import io.requery.Table;
import io.requery.Transient;
import lombok.NoArgsConstructor;
import static com.fastaccess.data.dao.model.User.FOLLOWER_NAME;
@ -68,6 +69,7 @@ public abstract class AbstractUser implements Parcelable {
@Column(name = "date_column") Date date;
String repoId;
String description;
@Transient boolean hasOrganizationProjects;
public void save(User entity) {
if (getUser(entity.getId()) != null) {

View File

@ -200,5 +200,4 @@ public class Bundler {
return get();
}
}

View File

@ -62,7 +62,7 @@ public class FileHelper {
title = cur.getString(cur.getColumnIndex(MediaStore.Audio.Media.TITLE));
}
}
}
} catch (Exception ignored) {}
}
}
return title;

View File

@ -103,6 +103,7 @@ public class PrefGetter {
private static final String ENTERPRISE_URL = "enterprise_url";
private static final String NOTIFICATION_SOUND_PATH = "notification_sound_path";
private static final String DISABLE_AUTO_PLAY_GIF = "disable_auto_play_gif";
private static final String PLAY_STORE_REVIEW_ACTIVITY = "play_store_review_activity";
public static void setToken(@Nullable String token) {
PrefHelper.set(TOKEN, token);
@ -468,4 +469,12 @@ public class PrefGetter {
public static boolean isAppAnimationDisabled() {
return PrefHelper.getBoolean("app_animation");
}
public static boolean isPlayStoreWarningShowed() {
return PrefHelper.getBoolean(PLAY_STORE_REVIEW_ACTIVITY);
}
public static void setPlayStoreWarningShowed() {
PrefHelper.set(PLAY_STORE_REVIEW_ACTIVITY, true);
}
}

View File

@ -17,9 +17,7 @@ class CachedComments private constructor() {
return map["$repo/$login/$number"]
}
fun clear() {
map.clear()
}
fun clear() = map.clear()
private object Holder {
val INSTANCE = CachedComments()

View File

@ -10,6 +10,7 @@ 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;
@ -256,19 +257,11 @@ public class MarkDownProvider {
}
public static void addPhoto(@NonNull EditText editText) {
addLink(editText, "", "");
}
public static void addPhoto(@NonNull EditText editText, @NonNull String title, @NonNull String link) {
String result = "![" + InputHelper.toString(title) + "](" + InputHelper.toString(link) + ")";
insertAtCursor(editText, result);
}
public static void addLink(@NonNull EditText editText) {
addLink(editText, "", "");
}
public static void addLink(@NonNull EditText editText, @NonNull String title, @NonNull String link) {
String result = "[" + InputHelper.toString(title) + "](" + InputHelper.toString(link) + ")";
insertAtCursor(editText, result);
@ -319,10 +312,18 @@ public class MarkDownProvider {
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());
int start = editText.getSelectionStart();
int end = editText.getSelectionEnd();
Logger.e(start, end);
if (start >= 0 && end > 0 && start != end) {
editText.setText(editText.getText().replace(start, end, text));
} else {
int index = editText.getSelectionStart() >= 0 ? editText.getSelectionStart() : 0;
Logger.e(start, end, index);
StringBuilder builder = new StringBuilder(oriContent);
builder.insert(index, text);
editText.setText(builder.toString());
editText.setSelection(index + text.length());
}
}
}

View File

@ -29,6 +29,7 @@ import com.fastaccess.ui.modules.repos.code.files.activity.RepoFilesActivity;
import com.fastaccess.ui.modules.repos.code.releases.ReleasesListActivity;
import com.fastaccess.ui.modules.repos.issues.create.CreateIssueActivity;
import com.fastaccess.ui.modules.repos.issues.issue.details.IssuePagerActivity;
import com.fastaccess.ui.modules.repos.projects.details.ProjectPagerActivity;
import com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.PullRequestPagerActivity;
import com.fastaccess.ui.modules.repos.wiki.WikiActivity;
import com.fastaccess.ui.modules.search.SearchActivity;
@ -132,6 +133,7 @@ public class SchemeParser {
if (TextUtils.equals(authority, HOST_DEFAULT) || TextUtils.equals(authority, RAW_AUTHORITY) ||
TextUtils.equals(authority, API_AUTHORITY) || isEnterprise) {
Intent trending = getTrending(context, data);
Intent projects = getRepoProject(context, data);
Intent userIntent = getUser(context, data);
Intent repoIssues = getRepoIssueIntent(context, data);
Intent repoPulls = getRepoPullRequestIntent(context, data);
@ -144,8 +146,9 @@ public class SchemeParser {
Intent commit = getCommit(context, data, showRepoBtn);
Intent commits = getCommits(context, data, showRepoBtn);
Intent blob = getBlob(context, data);
Optional<Intent> intentOptional = returnNonNull(trending, userIntent, repoIssues, repoPulls, pullRequestIntent, commit, commits,
createIssueIntent, issueIntent, releasesIntent, repoIntent, repoWikiIntent, blob);
Optional<Intent> intentOptional = returnNonNull(trending, projects, userIntent, repoIssues, repoPulls,
pullRequestIntent, commit, commits, createIssueIntent, issueIntent, releasesIntent, repoIntent,
repoWikiIntent, blob);
Optional<Intent> empty = Optional.empty();
if (intentOptional != null && intentOptional.isPresent() && intentOptional != empty) {
Intent intent = intentOptional.get();
@ -264,6 +267,25 @@ public class SchemeParser {
}
}
@Nullable private static Intent getRepoProject(@NonNull Context context, @NonNull Uri uri) {
List<String> segments = uri.getPathSegments();
if (segments == null || segments.size() < 3) return null;
String owner = segments.get(0);
String repoName = segments.get(1);
if (segments.size() == 3 && "projects".equalsIgnoreCase(segments.get(2))) {
return RepoPagerActivity.createIntent(context, repoName, owner, RepoPagerMvp.PROJECTS);
} else if (segments.size() == 4 && "projects".equalsIgnoreCase(segments.get(2))) {
try {
int projectId = Integer.parseInt(segments.get(segments.size() - 1));
if (projectId > 0) {
return ProjectPagerActivity.Companion.getIntent(context, owner, repoName, projectId,
LinkParserHelper.isEnterprise(uri.toString()));
}
} catch (Exception ignored) {}
}
return null;
}
@Nullable private static Intent getWiki(@NonNull Context context, @NonNull Uri uri) {
List<String> segments = uri.getPathSegments();
if (segments == null || segments.size() < 3) return null;

View File

@ -19,6 +19,7 @@ import com.fastaccess.provider.scheme.SchemeParser;
import com.fastaccess.provider.timeline.handler.BetterLinkMovementExtended;
import com.fastaccess.provider.timeline.handler.DrawableHandler;
import com.fastaccess.provider.timeline.handler.EmojiHandler;
import com.fastaccess.provider.timeline.handler.HeaderHandler;
import com.fastaccess.provider.timeline.handler.HrHandler;
import com.fastaccess.provider.timeline.handler.ItalicHandler;
import com.fastaccess.provider.timeline.handler.LinkHandler;
@ -86,7 +87,7 @@ public class HtmlHelper {
mySpanner.setStripExtraWhiteSpace(true);
mySpanner.registerHandler("pre", new PreTagHandler(windowBackground, true, theme));
mySpanner.registerHandler("code", new PreTagHandler(windowBackground, false, theme));
mySpanner.registerHandler("img", new DrawableHandler(textView));
mySpanner.registerHandler("img", new DrawableHandler(textView, width));
mySpanner.registerHandler("g-emoji", new EmojiHandler());
mySpanner.registerHandler("blockquote", new QouteHandler(windowBackground));
mySpanner.registerHandler("b", new BoldHandler());
@ -106,6 +107,12 @@ public class HtmlHelper {
mySpanner.registerHandler("hr", new HrHandler(windowBackground, width, false));
mySpanner.registerHandler("emoji", new EmojiHandler());
mySpanner.registerHandler("mention", new LinkHandler());
mySpanner.registerHandler("h1", new HeaderHandler(1.5F));
mySpanner.registerHandler("h2", new HeaderHandler(1.4F));
mySpanner.registerHandler("h3", new HeaderHandler(1.3F));
mySpanner.registerHandler("h4", new HeaderHandler(1.2F));
mySpanner.registerHandler("h5", new HeaderHandler(1.1F));
mySpanner.registerHandler("h6", new HeaderHandler(1.0F));
if (width > 0) {
TableHandler tableHandler = new TableHandler();
tableHandler.setTextColor(ViewHelper.generateTextColor(windowBackground));
@ -116,15 +123,14 @@ public class HtmlHelper {
}
@ColorInt public static int getWindowBackground(@PrefGetter.ThemeType int theme) {
switch (theme) {
case PrefGetter.AMLOD:
return Color.parseColor("#0B162A");
case PrefGetter.BLUISH:
return Color.parseColor("#111C2C");
case PrefGetter.DARK:
return Color.parseColor("#22252A");
default:
return Color.parseColor("#EEEEEE");
if (theme == PrefGetter.AMLOD) {
return Color.parseColor("#0B162A");
} else if (theme == PrefGetter.BLUISH) {
return Color.parseColor("#111C2C");
} else if (theme == PrefGetter.DARK) {
return Color.parseColor("#22252A");
} else {
return Color.parseColor("#EEEEEE");
}
}

View File

@ -8,6 +8,7 @@ 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;
@ -22,6 +23,7 @@ import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
@AllArgsConstructor public class DrawableHandler extends TagNodeHandler {
private TextView textView;
private int width;
@SuppressWarnings("ConstantConditions") private boolean isNull() {
return textView == null;
@ -32,8 +34,9 @@ import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
if (!InputHelper.isEmpty(src)) {
builder.append("");
if (isNull()) return;
DrawableGetter imageGetter = new DrawableGetter(textView);
DrawableGetter imageGetter = new DrawableGetter(textView, width);
builder.setSpan(new ImageSpan(imageGetter.getDrawable(src)), start, builder.length(), SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new CenterSpan(), start, builder.length(), SPAN_EXCLUSIVE_EXCLUSIVE);
appendNewLine(builder);
}
}

View File

@ -0,0 +1,33 @@
package com.fastaccess.provider.timeline.handler
import android.text.SpannableStringBuilder
import android.text.style.RelativeSizeSpan
import net.nightwhistler.htmlspanner.TagNodeHandler
import net.nightwhistler.htmlspanner.spans.FontFamilySpan
import org.htmlcleaner.TagNode
/**
* Created by Kosh on 29.09.17.
*/
class HeaderHandler(val size: Float) : TagNodeHandler() {
override fun beforeChildren(node: TagNode?, builder: SpannableStringBuilder?) {
appendNewLine(builder)
}
override fun handleTagNode(node: TagNode, builder: SpannableStringBuilder, start: Int, end: Int) {
builder.setSpan(RelativeSizeSpan(this.size), start, end, 33)
val originalSpan = this.getFontFamilySpan(builder, start, end)
val boldSpan: FontFamilySpan
if (originalSpan == null) {
boldSpan = FontFamilySpan(this.spanner.defaultFont)
} else {
boldSpan = FontFamilySpan(originalSpan.fontFamily)
boldSpan.isItalic = originalSpan.isItalic
}
boldSpan.isBold = true
builder.setSpan(boldSpan, start, end, 33)
appendNewLine(builder)
}
}

View File

@ -4,6 +4,7 @@ import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.text.SpannableStringBuilder;
import com.fastaccess.helper.Logger;
import com.fastaccess.ui.widgets.SpannableBuilder;
import net.nightwhistler.htmlspanner.TagNodeHandler;
@ -42,10 +43,11 @@ import lombok.NoArgsConstructor;
return node.getParent() == null ? null : node.getParent().getName();
}
@Override public void beforeChildren(TagNode node, SpannableStringBuilder builder) {
@Override public void beforeChildren(TagNode node, SpannableStringBuilder builder) {
TodoItems todoItem = null;
if (node.getChildTags() != null && node.getChildTags().length > 0) {
for (TagNode tagNode : node.getChildTags()) {
Logger.e(tagNode.getName(), tagNode.getText());
if (tagNode.getName() != null && tagNode.getName().equals("input")) {
todoItem = new TodoItems();
todoItem.isChecked = tagNode.getAttributeByName("checked") != null;

View File

@ -20,10 +20,8 @@ public class MarginHandler extends TagNodeHandler {
}
}
public void handleTagNode(TagNode node, SpannableStringBuilder builder, int start, int end) {
builder.setSpan(new LeadingMarginSpan.Standard(30), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
this.appendNewLine(builder);
this.appendNewLine(builder);
}
}

View File

@ -21,8 +21,7 @@ import lombok.AllArgsConstructor;
public void handleTagNode(TagNode node, SpannableStringBuilder builder, int start, int end) {
builder.append("\n");
builder.setSpan(new MarkDownQuoteSpan(color), start, builder.length(), 33);
builder.setSpan(new MarkDownQuoteSpan(color), (start > builder.length() - 1) ? start + 1 : start, builder.length() - 1, 33);
builder.append("\n");
}
}

View File

@ -19,7 +19,6 @@ import android.text.style.AlignmentSpan;
import android.text.style.ImageSpan;
import net.nightwhistler.htmlspanner.TagNodeHandler;
import net.nightwhistler.htmlspanner.spans.CenterSpan;
import org.htmlcleaner.TagNode;
@ -38,58 +37,42 @@ public class TableHandler extends TagNodeHandler {
private int tableWidth = 500;
private Typeface typeFace = Typeface.DEFAULT;
private float textSize = 30f;
private float textSize = 28f;
private int textColor = Color.BLACK;
private static final int PADDING = 20;
/**
* Sets how wide the table should be.
*
* @param tableWidth
*/
@Override public boolean rendersContent() {
return true;
}
@Override public void handleTagNode(TagNode node, SpannableStringBuilder builder, int start, int end) {
Table table = getTable(node);
for (int i = 0; i < table.getRows().size(); i++) {
List<Spanned> row = table.getRows().get(i);
builder.append("\uFFFC");
TableRowDrawable drawable = new TableRowDrawable(row, table.isDrawBorder());
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
builder.setSpan(new ImageSpan(drawable), start + i, builder.length(), 33);
}
builder.append("\uFFFC");
Drawable drawable = new TableRowDrawable(new ArrayList<Spanned>(), table.isDrawBorder());
drawable.setBounds(0, 0, tableWidth, 1);
builder.setSpan(new ImageSpan(drawable), builder.length() - 1, builder.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan((AlignmentSpan) () -> Alignment.ALIGN_CENTER, start, builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.append("\n");
}
public void setTableWidth(int tableWidth) {
this.tableWidth = tableWidth;
}
/**
* Sets the text colour to use.
* <p>
* Default is black.
*
* @param textColor
*/
public void setTextColor(int textColor) {
this.textColor = textColor;
}
/**
* Sets the font size to use.
* <p>
* Default is 16f.
*
* @param textSize
*/
public void setTextSize(float textSize) {
this.textSize = textSize;
}
/**
* Sets the TypeFace to use.
* <p>
* Default is Typeface.DEFAULT
*
* @param typeFace
*/
public void setTypeFace(Typeface typeFace) {
this.typeFace = typeFace;
}
@Override
public boolean rendersContent() {
return true;
}
private void readNode(Object node, Table table) {
if (node instanceof TagNode) {
TagNode tagNode = (TagNode) node;
@ -144,44 +127,19 @@ public class TableHandler extends TagNodeHandler {
int rowHeight = 0;
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();
}
for (Spanned cell : row) {
StaticLayout layout = new StaticLayout(cell, textPaint, columnWidth
- 2 * PADDING, Alignment.ALIGN_NORMAL, 1.5f, 0.5f, true);
if (layout.getHeight() > rowHeight) {
rowHeight = layout.getHeight();
}
}
return rowHeight;
}
@Override public void handleTagNode(TagNode node, SpannableStringBuilder builder, int start, int end) {
Table table = getTable(node);
for (int i = 0; i < table.getRows().size(); i++) {
List<Spanned> row = table.getRows().get(i);
builder.append("\uFFFC");
TableRowDrawable drawable = new TableRowDrawable(row, table.isDrawBorder());
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
builder.setSpan(new ImageSpan(drawable), start + i, builder.length(), 33);
}
builder.append("\uFFFC");
Drawable drawable = new TableRowDrawable(new ArrayList<>(), table.isDrawBorder());
drawable.setBounds(0, 0, tableWidth, 1);
builder.setSpan(new ImageSpan(drawable), builder.length() - 1, builder.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan((AlignmentSpan) () -> Alignment.ALIGN_CENTER, start, builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new CenterSpan(), start, builder.length(), 33);
builder.append("\n");
}
/**
* Drawable of the table, which does the actual rendering.
*
* @author Alex Kuiper.
*/
private class TableRowDrawable extends Drawable {
private List<Spanned> tableRow;
@ -222,7 +180,7 @@ public class TableHandler extends TagNodeHandler {
StaticLayout layout = new StaticLayout(tableRow.get(i),
getTextPaint(), (columnWidth - 2 * PADDING),
Alignment.ALIGN_NORMAL, 1f, 0f, true);
Alignment.ALIGN_NORMAL, 1.5f, 0.5f, true);
canvas.translate(offset + PADDING, 0);
layout.draw(canvas);

View File

@ -21,11 +21,13 @@ import java.util.Set;
public class DrawableGetter implements Html.ImageGetter, Drawable.Callback {
private WeakReference<TextView> container;
private final Set<GlideDrawableTarget> cachedTargets;
private final int width;
public DrawableGetter(TextView tv) {
public DrawableGetter(TextView tv, int width) {
tv.setTag(R.id.drawable_callback, this);
this.container = new WeakReference<>(tv);
this.cachedTargets = new HashSet<>();
this.width = width;
}
@Override public Drawable getDrawable(@NonNull String url) {
@ -35,7 +37,7 @@ public class DrawableGetter implements Html.ImageGetter, Drawable.Callback {
final GenericRequestBuilder load = Glide.with(context)
.load(url)
.dontAnimate();
final GlideDrawableTarget target = new GlideDrawableTarget(urlDrawable, container);
final GlideDrawableTarget target = new GlideDrawableTarget(urlDrawable, container, width);
load.into(target);
cachedTargets.add(target);
}

View File

@ -15,17 +15,28 @@ import java.lang.ref.WeakReference;
class GlideDrawableTarget extends SimpleTarget<GlideDrawable> {
private final UrlDrawable urlDrawable;
private final WeakReference<TextView> container;
private final int width;
GlideDrawableTarget(UrlDrawable urlDrawable, WeakReference<TextView> container) {
GlideDrawableTarget(UrlDrawable urlDrawable, WeakReference<TextView> container, int width) {
this.urlDrawable = urlDrawable;
this.container = container;
this.width = width;
}
@Override public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
if (container != null && container.get() != null) {
TextView textView = container.get();
float width = (float) (resource.getIntrinsicWidth() / 1.3);
float height = (float) (resource.getIntrinsicHeight() / 1.3);
float width;
float height;
if (resource.getIntrinsicWidth() >= this.width) {
float downScale = (float) resource.getIntrinsicWidth() / this.width;
width = (float) (resource.getIntrinsicWidth() / downScale / 1.3);
height = (float) (resource.getIntrinsicHeight() / downScale / 1.3);
} else {
float multiplier = (float) this.width / resource.getIntrinsicWidth();
width = (float) resource.getIntrinsicWidth() * multiplier;
height = (float) resource.getIntrinsicHeight() * multiplier;
}
Rect rect = new Rect(0, 0, Math.round(width), Math.round(height));
resource.setBounds(rect);
urlDrawable.setBounds(rect);

View File

@ -1,5 +1,6 @@
package com.fastaccess.ui.adapter.viewholder;
import android.graphics.Color;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.transition.ChangeBounds;
@ -10,6 +11,7 @@ import android.view.ViewGroup;
import android.widget.TextView;
import com.fastaccess.R;
import com.fastaccess.data.dao.LabelModel;
import com.fastaccess.data.dao.ReactionsModel;
import com.fastaccess.data.dao.TimelineModel;
import com.fastaccess.data.dao.model.Issue;
@ -17,6 +19,7 @@ import com.fastaccess.data.dao.model.PullRequest;
import com.fastaccess.data.dao.model.User;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.ParseDateFormat;
import com.fastaccess.helper.ViewHelper;
import com.fastaccess.provider.scheme.LinkParserHelper;
import com.fastaccess.provider.timeline.CommentsHelper;
import com.fastaccess.provider.timeline.HtmlHelper;
@ -25,11 +28,13 @@ import com.fastaccess.ui.adapter.callback.OnToggleView;
import com.fastaccess.ui.adapter.callback.ReactionsCallback;
import com.fastaccess.ui.widgets.AvatarLayout;
import com.fastaccess.ui.widgets.FontTextView;
import com.fastaccess.ui.widgets.LabelSpan;
import com.fastaccess.ui.widgets.SpannableBuilder;
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter;
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder;
import java.util.Date;
import java.util.List;
import butterknife.BindView;
@ -56,6 +61,8 @@ public class IssueDetailsViewHolder extends BaseViewHolder<TimelineModel> {
@BindView(R.id.emojiesList) View emojiesList;
@BindView(R.id.reactionsText) TextView reactionsText;
@BindView(R.id.owner) TextView owner;
@BindView(R.id.labels) TextView labels;
@BindView(R.id.labelsHolder) View labelsHolder;
private OnToggleView onToggleView;
private ReactionsCallback reactionsCallback;
private ViewGroup viewGroup;
@ -172,11 +179,13 @@ public class IssueDetailsViewHolder extends BaseViewHolder<TimelineModel> {
private void bind(@NonNull Issue issueModel) {
setup(issueModel.getUser(), issueModel.getBodyHtml(), issueModel.getReactions());
setupDate(issueModel.getCreatedAt(), issueModel.getUpdatedAt());
setupLabels(issueModel.getLabels());
}
private void bind(@NonNull PullRequest pullRequest) {
setup(pullRequest.getUser(), pullRequest.getBodyHtml(), pullRequest.getReactions());
setupDate(pullRequest.getCreatedAt(), pullRequest.getUpdatedAt());
setupLabels(pullRequest.getLabels());
}
private void setup(User user, String description, ReactionsModel reactionsModel) {
@ -193,8 +202,8 @@ public class IssueDetailsViewHolder extends BaseViewHolder<TimelineModel> {
if (reactionsModel != null) {
appendEmojies(reactionsModel);
}
if (description != null && !description.trim().isEmpty()) {
HtmlHelper.htmlIntoTextView(comment, description, viewGroup.getWidth());
if (!InputHelper.isEmpty(description)) {
HtmlHelper.htmlIntoTextView(comment, description, viewGroup.getWidth() - ViewHelper.dpToPx(itemView.getContext(), 24));
} else {
comment.setText(R.string.no_description_provided);
}
@ -204,6 +213,21 @@ public class IssueDetailsViewHolder extends BaseViewHolder<TimelineModel> {
date.setText(ParseDateFormat.getTimeAgo(createdDate));
}
private void setupLabels(@Nullable List<LabelModel> labelList) {
if (labelList != null && !labelList.isEmpty()) {
SpannableBuilder builder = SpannableBuilder.builder();
for (LabelModel labelModel : labelList) {
int color = Color.parseColor("#" + labelModel.getColor());
builder.append(" ").append(" " + labelModel.getName() + " ", new LabelSpan(color));
}
labels.setText(builder);
labelsHolder.setVisibility(View.VISIBLE);
} else {
labels.setText("");
labelsHolder.setVisibility(View.GONE);
}
}
private void appendEmojies(@NonNull ReactionsModel reaction) {
SpannableBuilder spannableBuilder = SpannableBuilder.builder();
reactionsText.setText("");

View File

@ -402,8 +402,8 @@ class PullRequestEventViewHolder private constructor(view: View, adapter: BaseRe
if (value == null) {
return ""
}
if (value.length <= 7) return value
else return value.substring(0, 7)
return if (value.length <= 7) value
else value.substring(0, 7)
}
companion object {

View File

@ -108,8 +108,13 @@ public class PullRequestFilesViewHolder extends BaseViewHolder<CommitFileChanges
if (model.getLinesModel().size() <= 100) {
patch.setAdapter(new CommitLinesAdapter(model.getLinesModel(), this));
patch.setVisibility(View.VISIBLE);
} else if (CommitFileChanges.canAttachToBundle(model)) {
if (adapter.getListener() != null) {
//noinspection unchecked
adapter.getListener().onItemClick(position, patch, model);
}
} else {
Toasty.warning(itemView.getContext(),itemView.getResources().getString(R.string.too_large_changes)).show();
Toasty.warning(itemView.getContext(), itemView.getResources().getString(R.string.too_large_changes)).show();
return;
}
} else {

View File

@ -6,6 +6,6 @@ import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
/**
* Created by kosh on 07/08/2017.
*/
class UnknownTypeViewHolder(private val view: View) : BaseViewHolder<Any>(view) {
class UnknownTypeViewHolder(view: View) : BaseViewHolder<Any>(view) {
override fun bind(t: Any) {} //DO NOTHING
}

View File

@ -44,6 +44,7 @@ import com.fastaccess.ui.modules.gists.gist.GistActivity;
import com.fastaccess.ui.modules.login.chooser.LoginChooserActivity;
import com.fastaccess.ui.modules.main.MainActivity;
import com.fastaccess.ui.modules.main.orgs.OrgListDialogFragment;
import com.fastaccess.ui.modules.main.playstore.PlayStoreWarningActivity;
import com.fastaccess.ui.modules.repos.code.commit.details.CommitPagerActivity;
import com.fastaccess.ui.modules.repos.issues.issue.details.IssuePagerActivity;
import com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.PullRequestPagerActivity;
@ -107,29 +108,11 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
setContentView(layout());
ButterKnife.bind(this);
}
if (!isSecured()) {
if (!isLoggedIn()) {
onRequireLogin();
return;
}
}
if (savedInstanceState != null && !savedInstanceState.isEmpty()) {
StateSaver.restoreInstanceState(this, savedInstanceState);
getPresenter().onRestoreInstanceState(presenterStateBundle);
}
if (!validateAuth()) return;
launchPlayStoreReviewActivity();
initPresenterBundle(savedInstanceState);
setupToolbarAndStatusBar(toolbar);
if (savedInstanceState == null) {
if (getIntent() != null) {
if (getIntent().getExtras() != null) {
getPresenter().setEnterprise(getIntent().getExtras().getBoolean(BundleConstant.IS_ENTERPRISE));
} else if (getIntent().hasExtra(BundleConstant.IS_ENTERPRISE)) {
getPresenter().setEnterprise(getIntent().getBooleanExtra(BundleConstant.IS_ENTERPRISE, false));
}
}
if (PrefGetter.showWhatsNew()) {
new ChangelogBottomSheetDialog().show(getSupportFragmentManager(), "ChangelogBottomSheetDialog");
}
}
initEnterpriseExtra(savedInstanceState);
mainNavDrawer = new MainNavDrawer(this, extraNav, accountsNav);
setupNavigationView();
setupDrawer();
@ -492,4 +475,43 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
CachedComments.Companion.getInstance().clear();
}
}
private boolean validateAuth() {
if (!isSecured()) {
if (!isLoggedIn()) {
onRequireLogin();
return false;
}
}
return true;
}
private void initEnterpriseExtra(@Nullable Bundle savedInstanceState) {
if (savedInstanceState == null) {
if (getIntent() != null) {
if (getIntent().getExtras() != null) {
getPresenter().setEnterprise(getIntent().getExtras().getBoolean(BundleConstant.IS_ENTERPRISE));
} else if (getIntent().hasExtra(BundleConstant.IS_ENTERPRISE)) {
getPresenter().setEnterprise(getIntent().getBooleanExtra(BundleConstant.IS_ENTERPRISE, false));
}
}
}
}
private void initPresenterBundle(@Nullable Bundle savedInstanceState) {
if (savedInstanceState != null && !savedInstanceState.isEmpty()) {
StateSaver.restoreInstanceState(this, savedInstanceState);
getPresenter().onRestoreInstanceState(presenterStateBundle);
}
}
private void launchPlayStoreReviewActivity() {
if (!PrefGetter.isPlayStoreWarningShowed() && !(this instanceof PlayStoreWarningActivity)) {
startActivity(new Intent(this, PlayStoreWarningActivity.class));
} else {
if (PrefGetter.showWhatsNew() && !(this instanceof PlayStoreWarningActivity)) {
new ChangelogBottomSheetDialog().show(getSupportFragmentManager(), "ChangelogBottomSheetDialog");
}
}
}
}

View File

@ -22,6 +22,7 @@ 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;
import com.fastaccess.ui.widgets.dialog.ProgressDialogFragment;
import net.grandcentrix.thirtyinch.TiDialogFragment;
@ -37,6 +38,7 @@ public abstract class BaseDialogFragment<V extends BaseMvp.FAView, P extends Bas
protected BaseMvp.FAView callback;
@Nullable private Unbinder unbinder;
protected boolean suppressAnimation = false;
@LayoutRes protected abstract int fragmentLayout();
@ -71,6 +73,10 @@ public abstract class BaseDialogFragment<V extends BaseMvp.FAView, P extends Bas
}
@Override public void dismiss() {
if(suppressAnimation){
super.dismiss();
return;
}
if (PrefGetter.isAppAnimationDisabled()) {
super.dismiss();
} else {
@ -98,7 +104,7 @@ public abstract class BaseDialogFragment<V extends BaseMvp.FAView, P extends Bas
@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) {
final Dialog dialog = super.onCreateDialog(savedInstanceState);
if (!PrefGetter.isAppAnimationDisabled()) {
if (!PrefGetter.isAppAnimationDisabled() && !(this instanceof ProgressDialogFragment)) {
dialog.setOnShowListener(dialogInterface -> AnimHelper.revealDialog(dialog,
getResources().getInteger(android.R.integer.config_longAnimTime)));
}

View File

@ -20,6 +20,7 @@ import com.fastaccess.ui.modules.about.FastHubAboutActivity
import com.fastaccess.ui.modules.gists.GistsListActivity
import com.fastaccess.ui.modules.login.chooser.LoginChooserActivity
import com.fastaccess.ui.modules.main.MainActivity
import com.fastaccess.ui.modules.main.playstore.PlayStoreWarningActivity
import com.fastaccess.ui.modules.main.premium.PremiumActivity
import com.fastaccess.ui.modules.notification.NotificationActivity
import com.fastaccess.ui.modules.pinned.PinnedReposActivity
@ -38,13 +39,13 @@ class MainNavDrawer(val view: BaseActivity<*, *>, private val extraNav: Navigati
: BaseViewHolder.OnItemClickListener<Login> {
private var menusHolder: ViewGroup? = null
private val togglePinned: View? = view.findViewById<View>(R.id.togglePinned)
private val pinnedList: DynamicRecyclerView? = view.findViewById<DynamicRecyclerView>(R.id.pinnedList)
private val togglePinned: View? = view.findViewById(R.id.togglePinned)
private val pinnedList: DynamicRecyclerView? = view.findViewById(R.id.pinnedList)
private val pinnedListAdapter = PinnedReposAdapter(true)
private val userModel: Login? = Login.getUser()
init {
menusHolder = view.findViewById<ViewGroup>(R.id.menusHolder)
menusHolder = view.findViewById(R.id.menusHolder)
pinnedListAdapter.listener = object : BaseViewHolder.OnItemClickListener<PinnedRepos?> {
override fun onItemClick(position: Int, v: View?, item: PinnedRepos?) {
if (v != null && item != null) {
@ -181,6 +182,7 @@ class MainNavDrawer(val view: BaseActivity<*, *>, private val extraNav: Navigati
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))
item.itemId == R.id.faq -> view.startActivity(Intent(view, PlayStoreWarningActivity::class.java))
}
}
}, 250)

View File

@ -1,5 +1,6 @@
package com.fastaccess.ui.modules.changelog;
import android.app.Dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -61,6 +62,13 @@ public class ChangelogBottomSheetDialog extends BaseMvpBottomSheetDialogFragment
return new ChangelogPresenter();
}
@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
return dialog;
}
private void showChangelog(String html) {
if (prettifyWebView == null) return;
webProgress.setVisibility(View.GONE);

View File

@ -34,9 +34,9 @@ class EmojiBottomSheet : BaseMvpBottomSheetDialogFragment<EmojiMvp.View, EmojiPr
override fun onAttach(context: Context) {
super.onAttach(context)
when {
parentFragment is EmojiMvp.EmojiCallback -> emojiCallback = parentFragment as EmojiMvp.EmojiCallback
context is EmojiMvp.EmojiCallback -> emojiCallback = context
emojiCallback = when {
parentFragment is EmojiMvp.EmojiCallback -> parentFragment as EmojiMvp.EmojiCallback
context is EmojiMvp.EmojiCallback -> context
else -> throw IllegalArgumentException("${context.javaClass.simpleName} must implement EmojiMvp.EmojiCallback")
}
}

View File

@ -38,11 +38,12 @@ public class EditorLinkImageDialogFragment extends BaseDialogFragment<EditorLink
@BindView(R.id.link) TextInputLayout link;
@BindView(R.id.select) FontButton select;
public static EditorLinkImageDialogFragment newInstance(boolean isLink) {
public static EditorLinkImageDialogFragment newInstance(boolean isLink, @Nullable String link) {
EditorLinkImageDialogFragment fragment = new EditorLinkImageDialogFragment();
fragment.setArguments(Bundler
.start()
.put(BundleConstant.YES_NO_EXTRA, isLink)
.put(BundleConstant.ITEM, link)
.end());
return fragment;
}
@ -75,6 +76,9 @@ public class EditorLinkImageDialogFragment extends BaseDialogFragment<EditorLink
@Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
select.setVisibility(isLink() ? View.GONE : View.VISIBLE);
if (savedInstanceState == null) {
title.getEditText().setText(getArguments().getString(BundleConstant.ITEM));
}
}
@NonNull @Override public EditorLinkImagePresenter providePresenter() {

View File

@ -7,6 +7,7 @@ import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.view.MenuItem;
import com.fastaccess.R;
import com.fastaccess.data.dao.FragmentPagerAdapterModel;
@ -17,6 +18,7 @@ import com.fastaccess.ui.base.BaseActivity;
import com.fastaccess.ui.base.BaseFragment;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
import com.fastaccess.ui.modules.gists.create.CreateGistActivity;
import com.fastaccess.ui.modules.main.MainActivity;
import com.fastaccess.ui.widgets.ViewPagerView;
import net.grandcentrix.thirtyinch.TiPresenter;
@ -93,6 +95,15 @@ public class GistsListActivity extends BaseActivity {
}
}
@Override public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
startActivity(new Intent(this, MainActivity.class));
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
private void setupTabs() {
pager.setAdapter(new FragmentsPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapterModel.buildForGists(this)));
tabs.setupWithViewPager(pager);

View File

@ -31,6 +31,7 @@ import com.fastaccess.ui.adapter.FragmentsPagerAdapter;
import com.fastaccess.ui.base.BaseActivity;
import com.fastaccess.ui.base.BaseFragment;
import com.fastaccess.ui.modules.editor.comment.CommentEditorFragment;
import com.fastaccess.ui.modules.gists.GistsListActivity;
import com.fastaccess.ui.modules.gists.create.CreateGistActivity;
import com.fastaccess.ui.modules.gists.gist.comments.GistCommentsFragment;
import com.fastaccess.ui.modules.main.premium.PremiumActivity;
@ -164,6 +165,10 @@ public class GistActivity extends BaseActivity<GistMvp.View, GistPresenter>
.put(BundleConstant.EXTRA, true).end())
.show(getSupportFragmentManager(), MessageDialogView.TAG);
return true;
} else if (item.getItemId() == android.R.id.home) {
GistsListActivity.startActivity(this);
finish();
return true;
}
return super.onOptionsItemSelected(item);
}

View File

@ -34,7 +34,6 @@ import butterknife.OnClick;
import it.sephiroth.android.library.bottomnavigation.BottomNavigation;
import shortbread.Shortcut;
@Shortcut(id = "feeds", icon = R.drawable.ic_app_shortcut_github, shortLabelRes = R.string.feeds, rank = 1)
public class MainActivity extends BaseActivity<MainMvp.View, MainPresenter> implements MainMvp.View {
@State @MainMvp.NavigationType int navType = MainMvp.FEEDS;

View File

@ -38,7 +38,7 @@ class CheckPurchaseActivity : Activity() {
}
}
override fun onBackPressed() {}
override fun onBackPressed() = Unit
private fun startMainActivity() {
startActivity(Intent(this, MainActivity::class.java))

View File

@ -0,0 +1,44 @@
package com.fastaccess.ui.modules.main.playstore
import android.os.Build
import android.os.Bundle
import android.text.Html
import android.widget.TextView
import butterknife.OnClick
import com.fastaccess.R
import com.fastaccess.helper.PrefGetter
import com.fastaccess.ui.base.BaseActivity
import com.fastaccess.ui.base.mvp.BaseMvp
import com.fastaccess.ui.base.mvp.presenter.BasePresenter
/**
* Created by Hashemsergani on 21.09.17.
*/
class PlayStoreWarningActivity : BaseActivity<BaseMvp.FAView, BasePresenter<BaseMvp.FAView>>() {
@OnClick(R.id.done) fun onDone() {
PrefGetter.setPlayStoreWarningShowed()
finish()
}
override fun layout(): Int = R.layout.playstore_review_layout_warning
override fun isTransparent(): Boolean = true
override fun canBack(): Boolean = false
override fun isSecured(): Boolean = true
override fun providePresenter(): BasePresenter<BaseMvp.FAView> = BasePresenter()
override fun onBackPressed() {}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
findViewById<TextView>(R.id.description).text = Html.fromHtml(getString(R.string.fasthub_faq_description), Html.FROM_HTML_MODE_LEGACY)
} else {
findViewById<TextView>(R.id.description).text = Html.fromHtml(getString(R.string.fasthub_faq_description))
}
}
}

View File

@ -0,0 +1,48 @@
package com.github.b3er.rxfirebase.common;
import android.support.annotation.NonNull;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import io.reactivex.CompletableEmitter;
import io.reactivex.SingleEmitter;
public final class GmsTaskListeners {
private GmsTaskListeners() {
throw new AssertionError("No instances");
}
public static <T> OnCompleteListener<T> listener(@NonNull final SingleEmitter<T> emitter) {
return new OnCompleteListener<T>() {
@Override public void onComplete(@NonNull Task<T> task) {
if (!task.isSuccessful()) {
if (!emitter.isDisposed()) {
emitter.onError(task.getException());
}
return;
}
if (!emitter.isDisposed()) {
emitter.onSuccess(task.getResult());
}
}
};
}
public static OnCompleteListener<Void> listener(@NonNull final CompletableEmitter emitter) {
return new OnCompleteListener<Void>() {
@Override public void onComplete(@NonNull Task<Void> task) {
if (!task.isSuccessful()) {
if (!emitter.isDisposed()) {
emitter.onError(task.getException());
}
return;
}
if (!emitter.isDisposed()) {
emitter.onComplete();
}
}
};
}
}

View File

@ -16,7 +16,6 @@ import com.fastaccess.BuildConfig
import com.fastaccess.R
import com.fastaccess.helper.AppHelper
import com.fastaccess.helper.InputHelper
import com.fastaccess.helper.PrefGetter
import com.fastaccess.helper.ViewHelper
import com.fastaccess.provider.fabric.FabricProvider
import com.fastaccess.ui.base.BaseActivity
@ -76,7 +75,7 @@ class PremiumActivity : BaseActivity<PremiumMvp.View, PremiumPresenter>(), Premi
return true
}
@OnClick(R.id.close) fun onClose(): Unit = finish()
@OnClick(R.id.close) fun onClose() = finish()
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
@ -93,12 +92,10 @@ class PremiumActivity : BaseActivity<PremiumMvp.View, PremiumPresenter>(), Premi
override fun onSuccessfullyActivated() {
hideProgress()
successActivationHolder.visibility = View.VISIBLE
FabricProvider.logPurchase(InputHelper.toString(editText))
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()
}

View File

@ -1,9 +1,11 @@
package com.fastaccess.ui.modules.main.premium
import com.fastaccess.helper.Logger
import com.fastaccess.data.dao.ProUsersModel
import com.fastaccess.helper.PrefGetter
import com.fastaccess.helper.RxHelper
import com.fastaccess.ui.base.mvp.presenter.BasePresenter
import com.github.b3er.rxfirebase.database.data
import com.github.b3er.rxfirebase.database.rxUpdateChildren
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.database.GenericTypeIndicator
import io.reactivex.Observable
@ -15,25 +17,41 @@ import io.reactivex.Observable
class PremiumPresenter : BasePresenter<PremiumMvp.View>(), PremiumMvp.Presenter {
override fun onCheckPromoCode(promo: String) {
val ref = FirebaseDatabase.getInstance().reference
manageDisposable(RxHelper.getObservable(ref.child("promoCodes")
manageDisposable(RxHelper.getObservable(ref.child("fasthub_pro").child(promo)
.data()
.toObservable())
.doOnSubscribe { sendToView { it.showProgress(0) } }
.flatMap {
var exists: Boolean? = false
if (it.exists()) {
val gti = object : GenericTypeIndicator<ArrayList<String>>() {}
val map = it.getValue(gti)
exists = map?.contains(promo)
var user = ProUsersModel()
if (it.exists() && it.hasChildren()) {
val gti = object : GenericTypeIndicator<ProUsersModel>() {}
user = it.getValue(gti) ?: ProUsersModel()
if (user.isAllowed) {
if (user.type == 1) {
PrefGetter.setProItems()
user.isAllowed = false
user.count = user.count + 1
return@flatMap RxHelper.getObservable(ref.child("fasthub_pro").rxUpdateChildren(hashMapOf(Pair(promo, user)))
.toObservable<ProUsersModel>())
.map { true }
} else {
PrefGetter.setProItems()
PrefGetter.setEnterpriseItem()
user.count = user.count + 1
return@flatMap RxHelper.getObservable(ref.child("fasthub_pro").rxUpdateChildren(hashMapOf(Pair(promo, user)))
.toObservable<ProUsersModel>())
.map { true }
}
}
}
Logger.e(it.children, it.childrenCount, exists)
return@flatMap Observable.just(exists)
return@flatMap Observable.just(user.isAllowed)
}
.doOnComplete { sendToView { it.hideProgress() } }
.subscribe({
when (it) {
true -> sendToView { it.onSuccessfullyActivated() }
else -> sendToView { it.onNoMatch() }
if (it) {
sendToView { it.onSuccessfullyActivated() }
} else {
sendToView { it.onNoMatch() }
}
}, ::println))
}

View File

@ -21,6 +21,7 @@ import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.ParseDateFormat;
import com.fastaccess.provider.emoji.EmojiParser;
import com.fastaccess.ui.base.BaseFragment;
import com.fastaccess.ui.modules.profile.org.project.OrgProjectActivity;
import com.fastaccess.ui.widgets.AvatarLayout;
import com.fastaccess.ui.widgets.FontTextView;
@ -44,6 +45,7 @@ public class OrgProfileOverviewFragment extends BaseFragment<OrgProfileOverviewM
@BindView(R.id.link) FontTextView link;
@BindView(R.id.joined) FontTextView joined;
@BindView(R.id.progress) LinearLayout progress;
@BindView(R.id.projects) View projects;
@State User userModel;
@ -57,7 +59,15 @@ public class OrgProfileOverviewFragment extends BaseFragment<OrgProfileOverviewM
if (userModel != null) ActivityHelper.startCustomTab(getActivity(), userModel.getAvatarUrl());
}
@OnClick(R.id.projects) void onOpenProjects() {
OrgProjectActivity.Companion.startActivity(getContext(), getPresenter().getLogin(), isEnterprise());
}
@SuppressLint("ClickableViewAccessibility") @Override public void onInitViews(@Nullable User userModel) {
if (getView() != null) {
TransitionManager.beginDelayedTransition((ViewGroup) getView());
}
if (this.userModel != null) return;
progress.setVisibility(View.GONE);
if (userModel == null) return;
this.userModel = userModel;
@ -80,21 +90,23 @@ public class OrgProfileOverviewFragment extends BaseFragment<OrgProfileOverviewM
email.setText(userModel.getEmail());
link.setText(userModel.getBlog());
joined.setText(ParseDateFormat.getTimeAgo(userModel.getCreatedAt()));
if (InputHelper.isEmpty(userModel.getLocation())) {
location.setVisibility(GONE);
if (!InputHelper.isEmpty(userModel.getLocation())) {
location.setVisibility(View.VISIBLE);
}
if (InputHelper.isEmpty(userModel.getEmail())) {
email.setVisibility(GONE);
if (!InputHelper.isEmpty(userModel.getEmail())) {
email.setVisibility(View.VISIBLE);
}
if (InputHelper.isEmpty(userModel.getBlog())) {
link.setVisibility(GONE);
if (!InputHelper.isEmpty(userModel.getBlog())) {
link.setVisibility(View.VISIBLE);
}
if (InputHelper.isEmpty(userModel.getCreatedAt())) {
joined.setVisibility(GONE);
if (!InputHelper.isEmpty(userModel.getCreatedAt())) {
joined.setVisibility(View.VISIBLE);
}
if (getView() != null) {
TransitionManager.beginDelayedTransition((ViewGroup) getView());
if (!InputHelper.isEmpty(userModel.getEmail())) {
email.setVisibility(View.VISIBLE);
}
projects.setVisibility(userModel.isHasOrganizationProjects() ? View.VISIBLE : View.GONE);
}
@Override protected int fragmentLayout() {

View File

@ -0,0 +1,63 @@
package com.fastaccess.ui.modules.profile.org.project
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.support.design.widget.AppBarLayout
import butterknife.BindView
import com.evernote.android.state.State
import com.fastaccess.R
import com.fastaccess.helper.BundleConstant
import com.fastaccess.helper.Bundler
import com.fastaccess.ui.base.BaseActivity
import com.fastaccess.ui.base.mvp.BaseMvp
import com.fastaccess.ui.base.mvp.presenter.BasePresenter
import com.fastaccess.ui.modules.repos.projects.RepoProjectsFragmentPager
/**
* Created by Hashemsergani on 24.09.17.
*/
class OrgProjectActivity : BaseActivity<BaseMvp.FAView, BasePresenter<BaseMvp.FAView>>() {
@State var org: String? = null
@BindView(R.id.appbar) lateinit var appBar: AppBarLayout
override fun layout(): Int = R.layout.activity_fragment_layout
override fun isTransparent(): Boolean = true
override fun canBack(): Boolean = true
override fun isSecured(): Boolean = false
override fun providePresenter(): BasePresenter<BaseMvp.FAView> = BasePresenter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
appBar.elevation = 0f
appBar.stateListAnimator = null
if (savedInstanceState == null) {
org = intent.extras.getString(BundleConstant.ITEM)
val org = org
if (org != null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, RepoProjectsFragmentPager.newInstance(org),
RepoProjectsFragmentPager.TAG)
.commit()
}
}
toolbar?.apply { subtitle = org }
}
companion object {
fun startActivity(context: Context, org: String, isEnterprise: Boolean) {
val intent = Intent(context, OrgProjectActivity::class.java)
intent.putExtras(Bundler.start().put(BundleConstant.ITEM, org)
.put(BundleConstant.IS_ENTERPRISE, isEnterprise)
.end())
context.startActivity(intent)
}
}
}

View File

@ -341,7 +341,9 @@ public class RepoPagerActivity extends BaseActivity<RepoPagerMvp.View, RepoPager
}
this.navType = navType;
//noinspection WrongConstant
if (bottomNavigation.getSelectedIndex() != navType) bottomNavigation.setSelectedIndex(navType, true);
try {
if (bottomNavigation.getSelectedIndex() != navType) bottomNavigation.setSelectedIndex(navType, true);
} catch (Exception ignored) {}
showHideFab();
getPresenter().onModuleChanged(getSupportFragmentManager(), navType);
}

View File

@ -236,7 +236,7 @@ class RepoPagerPresenter extends BasePresenter<RepoPagerMvp.View> implements Rep
break;
case RepoPagerMvp.PROJECTS:
if (projectsFragmentPager == null) {
onAddAndHide(fragmentManager, RepoProjectsFragmentPager.Companion.newInstance(repoId(), login()), currentVisible);
onAddAndHide(fragmentManager, RepoProjectsFragmentPager.Companion.newInstance(login(), repoId()), currentVisible);
} else {
onShowHideFragment(fragmentManager, projectsFragmentPager, currentVisible);
}

View File

@ -188,9 +188,20 @@ public class CommitCommentsFragment extends BaseFragment<CommitCommentsMvp.View,
}
@Override public void onTagUser(@Nullable User user) {
if (commentsCallback != null && user != null) {
commentsCallback.onTagUser(user.getLogin());
}
Intent intent = new Intent(getContext(), EditorActivity.class);
intent.putExtras(Bundler
.start()
.put(BundleConstant.ID, getPresenter().repoId())
.put(BundleConstant.EXTRA_TWO, getPresenter().login())
.put(BundleConstant.EXTRA_THREE, getPresenter().sha())
.put(BundleConstant.EXTRA, user != null ? "@" + user.getLogin() : "")
.put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraType.NEW_COMMIT_COMMENT_EXTRA)
.putStringArrayList("participants", CommentsHelper.getUsersByTimeline(adapter.getData()))
.put(BundleConstant.IS_ENTERPRISE, isEnterprise())
.end());
View view = getActivity() != null && getActivity().findViewById(R.id.fab) != null ? getActivity().findViewById(R.id.fab) : recycler;
ActivityHelper.startReveal(this, intent, view, BundleConstant.REQUEST_CODE);
}
@Override public void onReply(User user, String message) {

View File

@ -34,9 +34,9 @@ class BranchesFragment : BaseFragment<BranchesMvp.View, BranchesPresenter>(), Br
override fun onAttach(context: Context) {
super.onAttach(context)
if (parentFragment is BranchesPagerListener) {
branchCallback = parentFragment as BranchesPagerListener
} else branchCallback = context as BranchesPagerListener
branchCallback = if (parentFragment is BranchesPagerListener) {
parentFragment as BranchesPagerListener
} else context as BranchesPagerListener
}
override fun onDetach() {

View File

@ -31,9 +31,9 @@ class BranchesPagerFragment : BaseDialogFragment<BaseMvp.FAView, BasePresenter<B
override fun onAttach(context: Context) {
super.onAttach(context)
if (parentFragment is BranchesMvp.BranchSelectionListener) {
branchCallback = parentFragment as BranchesMvp.BranchSelectionListener
} else branchCallback = context as BranchesMvp.BranchSelectionListener
branchCallback = if (parentFragment is BranchesMvp.BranchSelectionListener) {
parentFragment as BranchesMvp.BranchSelectionListener
} else context as BranchesMvp.BranchSelectionListener
}
override fun onDetach() {

View File

@ -26,6 +26,7 @@ public class MilestoneDialogFragment extends BaseDialogFragment implements Miles
private IssuePagerMvp.View issueCallback;
private PullRequestPagerMvp.View pullRequestCallback;
private MilestoneMvp.OnMilestoneSelected milestoneCallback;
public static MilestoneDialogFragment newInstance(@NonNull String login, @NonNull String repo) {
MilestoneDialogFragment view = new MilestoneDialogFragment();
@ -48,6 +49,12 @@ public class MilestoneDialogFragment extends BaseDialogFragment implements Miles
} else if (getParentFragment() instanceof PullRequestPagerMvp.View) {
pullRequestCallback = (PullRequestPagerMvp.View) getParentFragment();
}
if (context instanceof MilestoneMvp.OnMilestoneSelected) {
milestoneCallback = (MilestoneMvp.OnMilestoneSelected) context;
} else if (getParentFragment() instanceof MilestoneMvp.OnMilestoneSelected) {
milestoneCallback = (MilestoneMvp.OnMilestoneSelected) getParentFragment();
}
}
@Override public void onDetach() {
@ -65,7 +72,8 @@ public class MilestoneDialogFragment extends BaseDialogFragment implements Miles
@Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
if (savedInstanceState == null) {
Bundle bundle = getArguments();
com.fastaccess.ui.modules.repos.extras.milestone.MilestoneDialogFragment milestoneView = new com.fastaccess.ui.modules.repos.extras.milestone.MilestoneDialogFragment();
com.fastaccess.ui.modules.repos.extras.milestone.MilestoneDialogFragment milestoneView = new com.fastaccess.ui.modules.repos.extras
.milestone.MilestoneDialogFragment();
milestoneView.setArguments(bundle);
getChildFragmentManager()
.beginTransaction()
@ -77,5 +85,6 @@ public class MilestoneDialogFragment extends BaseDialogFragment implements Miles
@Override public void onMilestoneSelected(@NonNull MilestoneModel milestoneModel) {
if (issueCallback != null) issueCallback.onMileStoneSelected(milestoneModel);
if (pullRequestCallback != null) pullRequestCallback.onMileStoneSelected(milestoneModel);
if (milestoneCallback != null) milestoneCallback.onMilestoneSelected(milestoneModel);
}
}

View File

@ -34,9 +34,8 @@ class DeleteFileBottomSheetFragment : BaseBottomSheetDialog() {
}
}
@OnClick(R.id.cancel) fun onCancel() {
dismiss()
}
@OnClick(R.id.cancel)
fun onCancel() = dismiss()
override fun onAttach(context: Context?) {
super.onAttach(context)

View File

@ -3,34 +3,49 @@ package com.fastaccess.ui.modules.repos.issues.create;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
import android.support.transition.TransitionManager;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import com.danielstone.materialaboutlibrary.ConvenienceBuilder;
import com.evernote.android.state.State;
import com.fastaccess.App;
import com.fastaccess.BuildConfig;
import com.fastaccess.R;
import com.fastaccess.data.dao.LabelListModel;
import com.fastaccess.data.dao.LabelModel;
import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.model.Issue;
import com.fastaccess.data.dao.model.PullRequest;
import com.fastaccess.data.dao.model.User;
import com.fastaccess.helper.ActivityHelper;
import com.fastaccess.helper.AppHelper;
import com.fastaccess.helper.BundleConstant;
import com.fastaccess.helper.Bundler;
import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.Logger;
import com.fastaccess.helper.ViewHelper;
import com.fastaccess.provider.markdown.MarkDownProvider;
import com.fastaccess.ui.base.BaseActivity;
import com.fastaccess.ui.modules.editor.EditorActivity;
import com.fastaccess.ui.modules.repos.extras.assignees.AssigneesDialogFragment;
import com.fastaccess.ui.modules.repos.extras.labels.LabelsDialogFragment;
import com.fastaccess.ui.modules.repos.extras.milestone.create.MilestoneDialogFragment;
import com.fastaccess.ui.widgets.FontTextView;
import com.fastaccess.ui.widgets.LabelSpan;
import com.fastaccess.ui.widgets.SpannableBuilder;
import com.fastaccess.ui.widgets.dialog.MessageDialogView;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.OnClick;
import butterknife.OnTouch;
@ -45,11 +60,20 @@ public class CreateIssueActivity extends BaseActivity<CreateIssueMvp.View, Creat
@BindView(R.id.title) TextInputLayout title;
@BindView(R.id.description) FontTextView description;
@BindView(R.id.submit) View submit;
@BindView(R.id.issueMiscLayout) LinearLayout issueMiscLayout;
@BindView(R.id.assignee) FontTextView assignee;
@BindView(R.id.labels) FontTextView labels;
@BindView(R.id.milestoneTitle) FontTextView milestoneTitle;
@BindView(R.id.milestoneDescription) FontTextView milestoneDescription;
@State String repoId;
@State String login;
@State Issue issue;
@State PullRequest pullRequest;
@State boolean isFeedback;
@State ArrayList<LabelModel> labelModels = new ArrayList<>();
@State MilestoneModel milestoneModel;
@State ArrayList<User> users = new ArrayList<>();
private AlertDialog alertDialog;
private CharSequence savedText;
@ -177,6 +201,12 @@ public class CreateIssueActivity extends BaseActivity<CreateIssueMvp.View, Creat
finish();
}
@Override public void onShowIssueMisc() {
TransitionManager.beginDelayedTransition(findViewById(R.id.parent));
issueMiscLayout.setVisibility(getPresenter().isCollaborator() ? View.VISIBLE : View.GONE);
//TODO
}
@NonNull @Override public CreateIssuePresenter providePresenter() {
return new CreateIssuePresenter();
}
@ -214,6 +244,17 @@ public class CreateIssueActivity extends BaseActivity<CreateIssueMvp.View, Creat
}
}
if (issue != null) {
Logger.e(issue.getLabels(), issue.getMilestone(), issue.getAssignees());
if (issue.getLabels() != null) {
onSelectedLabels(new ArrayList<>(issue.getLabels()));
}
if (issue.getAssignees() != null) {
onSelectedAssignees(new ArrayList<>(issue.getAssignees()), false);
}
if (issue.getMilestone() != null) {
milestoneModel = issue.getMilestone();
onMilestoneSelected(milestoneModel);
}
if (!InputHelper.isEmpty(issue.getTitle())) {
if (title.getEditText() != null) title.getEditText().setText(issue.getTitle());
}
@ -222,6 +263,17 @@ public class CreateIssueActivity extends BaseActivity<CreateIssueMvp.View, Creat
}
}
if (pullRequest != null) {
if (pullRequest.getLabels() != null) {
onSelectedLabels(new ArrayList<>(pullRequest.getLabels()));
}
if (pullRequest.getAssignees() != null) {
users.addAll(pullRequest.getAssignees());
onSelectedAssignees(new ArrayList<>(pullRequest.getAssignees()), false);
}
if (pullRequest.getMilestone() != null) {
milestoneModel = pullRequest.getMilestone();
onMilestoneSelected(milestoneModel);
}
if (!InputHelper.isEmpty(pullRequest.getTitle())) {
if (title.getEditText() != null) title.getEditText().setText(pullRequest.getTitle());
}
@ -230,6 +282,7 @@ public class CreateIssueActivity extends BaseActivity<CreateIssueMvp.View, Creat
}
}
}
getPresenter().checkAuthority(login, repoId);
if (isFeedback || ("k0shk0sh".equalsIgnoreCase(login) && repoId.equalsIgnoreCase("FastHub"))) {
setTitle(R.string.submit_feedback);
getPresenter().onCheckAppVersion();
@ -295,6 +348,68 @@ public class CreateIssueActivity extends BaseActivity<CreateIssueMvp.View, Creat
}
@OnClick(R.id.submit) public void onClick() {
getPresenter().onSubmit(InputHelper.toString(title), savedText, login, repoId, issue, pullRequest);
getPresenter().onSubmit(InputHelper.toString(title), savedText, login, repoId, issue, pullRequest, labelModels, milestoneModel, users);
}
@OnClick({R.id.addAssignee, R.id.addLabels, R.id.addMilestone}) public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.addAssignee:
AssigneesDialogFragment.newInstance(login, repoId, false)
.show(getSupportFragmentManager(), "AssigneesDialogFragment");
break;
case R.id.addLabels:
LabelListModel labelModels = new LabelListModel();
labelModels.addAll(this.labelModels);
LabelsDialogFragment.newInstance(labelModels, repoId, login)
.show(getSupportFragmentManager(), "LabelsDialogFragment");
break;
case R.id.addMilestone:
MilestoneDialogFragment.newInstance(login, repoId)
.show(getSupportFragmentManager(), "MilestoneDialogFragment");
break;
}
}
@Override public void onSelectedLabels(@NonNull ArrayList<LabelModel> labelModels) {
this.labelModels.clear();
this.labelModels.addAll(labelModels);
SpannableBuilder builder = SpannableBuilder.builder();
for (int i = 0; i < labelModels.size(); i++) {
LabelModel labelModel = labelModels.get(i);
int color = Color.parseColor("#" + labelModel.getColor());
if (i > 0) {
builder.append(" ").append(" " + labelModel.getName() + " ", new LabelSpan(color));
} else {
builder.append(labelModel.getName() + " ", new LabelSpan(color));
}
}
this.labels.setText(builder);
}
@Override public void onMilestoneSelected(@NonNull MilestoneModel milestoneModel) {
Logger.e(milestoneModel.getTitle(), milestoneModel.getDescription(), milestoneModel.getNumber());
this.milestoneModel = milestoneModel;
milestoneTitle.setText(milestoneModel.getTitle());
if (!InputHelper.isEmpty(milestoneModel.getDescription())) {
milestoneDescription.setText(milestoneModel.getDescription());
milestoneDescription.setVisibility(View.VISIBLE);
} else {
milestoneDescription.setText(null);
milestoneDescription.setVisibility(View.GONE);
}
}
@Override public void onSelectedAssignees(@NonNull ArrayList<User> users, boolean isAssignees) {
this.users.clear();
this.users.addAll(users);
SpannableBuilder builder = SpannableBuilder.builder();
for (int i = 0; i < users.size(); i++) {
User user = users.get(i);
builder.append(user.getLogin());
if (i != users.size() - 1) {
builder.append(", ");
}
}
assignee.setText(builder);
}
}

View File

@ -4,9 +4,17 @@ import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.fastaccess.data.dao.LabelModel;
import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.model.Issue;
import com.fastaccess.data.dao.model.PullRequest;
import com.fastaccess.data.dao.model.User;
import com.fastaccess.ui.base.mvp.BaseMvp;
import com.fastaccess.ui.modules.repos.extras.assignees.AssigneesMvp;
import com.fastaccess.ui.modules.repos.extras.labels.LabelsMvp;
import com.fastaccess.ui.modules.repos.extras.milestone.MilestoneMvp;
import java.util.ArrayList;
/**
* Created by Kosh on 19 Feb 2017, 12:12 PM
@ -14,7 +22,8 @@ import com.fastaccess.ui.base.mvp.BaseMvp;
public interface CreateIssueMvp {
interface View extends BaseMvp.FAView {
interface View extends BaseMvp.FAView, LabelsMvp.SelectedLabelsListener, AssigneesMvp.SelectedAssigneesListener,
MilestoneMvp.OnMilestoneSelected {
void onSetCode(@NonNull CharSequence charSequence);
void onTitleError(boolean isEmptyTitle);
@ -26,14 +35,23 @@ public interface CreateIssueMvp {
void onSuccessSubmission(PullRequest issueModel);
void onShowUpdate();
void onShowIssueMisc();
}
interface Presenter extends BaseMvp.FAPresenter {
void checkAuthority(@NonNull String login, @NonNull String repoId);
void onActivityForResult(int resultCode, int requestCode, Intent intent);
void onSubmit(@NonNull String title, @NonNull CharSequence description, @NonNull String login,
@NonNull String repo, @Nullable Issue issueModel, @Nullable PullRequest pullRequestModel);
@NonNull String repo, @Nullable Issue issueModel, @Nullable PullRequest pullRequestModel,
@Nullable ArrayList<LabelModel> labels, @Nullable MilestoneModel milestoneModel,
@Nullable ArrayList<User> users);
void onCheckAppVersion();
boolean isCollaborator();
}
}

View File

@ -5,24 +5,47 @@ import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import com.fastaccess.BuildConfig;
import com.fastaccess.R;
import com.fastaccess.data.dao.CreateIssueModel;
import com.fastaccess.data.dao.IssueRequestModel;
import com.fastaccess.data.dao.LabelListModel;
import com.fastaccess.data.dao.LabelModel;
import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.UsersListModel;
import com.fastaccess.data.dao.model.Issue;
import com.fastaccess.data.dao.model.Login;
import com.fastaccess.data.dao.model.PullRequest;
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.RestProvider;
import com.fastaccess.ui.base.mvp.BaseMvp;
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
import java.util.ArrayList;
/**
* Created by Kosh on 19 Feb 2017, 12:18 PM
*/
public class CreateIssuePresenter extends BasePresenter<CreateIssueMvp.View> implements CreateIssueMvp.Presenter {
@com.evernote.android.state.State boolean isCollaborator;
@Override public void checkAuthority(@NonNull String login, @NonNull String repoId) {
manageViewDisposable(RxHelper.getObservable(RestProvider.getRepoService(isEnterprise()).
isCollaborator(login, repoId, Login.getUser().getLogin()))
.subscribe(booleanResponse -> {
isCollaborator = booleanResponse.code() == 204;
sendToView(CreateIssueMvp.View::onShowIssueMisc);
}, Throwable::printStackTrace));
}
@Override public void onActivityForResult(int resultCode, int requestCode, Intent intent) {
if (resultCode == Activity.RESULT_OK && requestCode == BundleConstant.REQUEST_CODE) {
if (intent != null && intent.getExtras() != null) {
@ -34,9 +57,11 @@ public class CreateIssuePresenter extends BasePresenter<CreateIssueMvp.View> imp
}
}
@Override public void onSubmit(@NonNull String title, @NonNull CharSequence description,
@NonNull String login, @NonNull String repo,
@Nullable Issue issue, @Nullable PullRequest pullRequestModel) {
@Override public void onSubmit(@NonNull String title, @NonNull CharSequence description, @NonNull String login,
@NonNull String repo, @Nullable Issue issue, @Nullable PullRequest pullRequestModel,
@Nullable ArrayList<LabelModel> labels, @Nullable MilestoneModel milestoneModel,
@Nullable ArrayList<User> users) {
boolean isEmptyTitle = InputHelper.isEmpty(title);
if (getView() != null) {
getView().onTitleError(isEmptyTitle);
@ -46,6 +71,17 @@ public class CreateIssuePresenter extends BasePresenter<CreateIssueMvp.View> imp
CreateIssueModel createIssue = new CreateIssueModel();
createIssue.setBody(InputHelper.toString(description));
createIssue.setTitle(title);
if (isCollaborator) {
if (labels != null && !labels.isEmpty()) {
createIssue.setLabels(Stream.of(labels).map(LabelModel::getName).collect(Collectors.toCollection(ArrayList::new)));
}
if (users != null && !users.isEmpty()) {
createIssue.setAssignees(Stream.of(users).map(User::getLogin).collect(Collectors.toCollection(ArrayList::new)));
}
if (milestoneModel != null) {
createIssue.setMilestone((long) milestoneModel.getNumber());
}
}
makeRestCall(RestProvider.getIssueService(isEnterprise()).createIssue(login, repo, createIssue),
issueModel -> {
if (issueModel != null) {
@ -59,6 +95,21 @@ public class CreateIssuePresenter extends BasePresenter<CreateIssueMvp.View> imp
issue.setBody(InputHelper.toString(description));
issue.setTitle(title);
int number = issue.getNumber();
if (isCollaborator) {
if (labels != null) {
LabelListModel labelModels = new LabelListModel();
labelModels.addAll(labels);
issue.setLabels(labelModels);
}
if (milestoneModel != null) {
issue.setMilestone(milestoneModel);
}
if (users != null) {
UsersListModel usersListModel = new UsersListModel();
usersListModel.addAll(users);
issue.setAssignees(usersListModel);
}
}
IssueRequestModel requestModel = IssueRequestModel.clone(issue, false);
makeRestCall(RestProvider.getIssueService(isEnterprise()).editIssue(login, repo, number, requestModel),
issueModel -> {
@ -73,6 +124,21 @@ public class CreateIssuePresenter extends BasePresenter<CreateIssueMvp.View> imp
int number = pullRequestModel.getNumber();
pullRequestModel.setBody(InputHelper.toString(description));
pullRequestModel.setTitle(title);
if (isCollaborator) {
if (labels != null) {
LabelListModel labelModels = new LabelListModel();
labelModels.addAll(labels);
pullRequestModel.setLabels(labelModels);
}
if (milestoneModel != null) {
pullRequestModel.setMilestone(milestoneModel);
}
if (users != null) {
UsersListModel usersListModel = new UsersListModel();
usersListModel.addAll(users);
pullRequestModel.setAssignees(usersListModel);
}
}
IssueRequestModel requestModel = IssueRequestModel.clone(pullRequestModel, false);
makeRestCall(RestProvider.getPullRequestService(isEnterprise()).editPullRequest(login, repo, number, requestModel)
.flatMap(pullRequest1 -> RestProvider.getIssueService(isEnterprise()).getIssue(login, repo, number),
@ -91,6 +157,7 @@ public class CreateIssuePresenter extends BasePresenter<CreateIssueMvp.View> imp
}
}
}
}
@Override public void onCheckAppVersion() {
@ -105,4 +172,8 @@ public class CreateIssuePresenter extends BasePresenter<CreateIssueMvp.View> imp
}
}, false);
}
@Override public boolean isCollaborator() {
return isCollaborator;
}
}

View File

@ -39,7 +39,7 @@ class RepoProjectsFragmentPager : BaseFragment<BaseMvp.FAView, BasePresenter<Bas
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
pager.adapter = FragmentsPagerAdapter(childFragmentManager, FragmentPagerAdapterModel.buildForRepoProjects(context,
arguments.getString(BundleConstant.EXTRA), arguments.getString(BundleConstant.ID)))
arguments.getString(BundleConstant.ID), arguments.getString(BundleConstant.EXTRA)))
tabs.setupWithViewPager(pager)
if (savedInstanceState != null) {
@Suppress("UNCHECKED_CAST")
@ -56,7 +56,7 @@ class RepoProjectsFragmentPager : BaseFragment<BaseMvp.FAView, BasePresenter<Bas
model.tabIndex = tabIndex
model.count = count
counts.add(model)
tabs?.let { updateCount(model) }
tabs.let { updateCount(model) }
}
private fun updateCount(model: TabsCountStateModel) {
@ -71,7 +71,7 @@ class RepoProjectsFragmentPager : BaseFragment<BaseMvp.FAView, BasePresenter<Bas
companion object {
val TAG = RepoProjectsFragmentPager::class.java.simpleName
fun newInstance(login: String, repoId: String): RepoProjectsFragmentPager {
fun newInstance(login: String, repoId: String? = null): RepoProjectsFragmentPager {
val fragment = RepoProjectsFragmentPager()
fragment.arguments = Bundler.start()
.put(BundleConstant.ID, repoId)

View File

@ -37,6 +37,9 @@ class ProjectColumnFragment : BaseFragment<ProjectColumnMvp.View, ProjectColumnP
@BindView(R.id.fastScroller) lateinit var fastScroller: RecyclerViewFastScroller
@BindView(R.id.columnName) lateinit var columnName: FontTextView
@BindView(R.id.editColumnHolder) lateinit var editColumnHolder: View
@BindView(R.id.editColumn) lateinit var editColumn: View
@BindView(R.id.addCard) lateinit var addCard: View
@BindView(R.id.deleteColumn) lateinit var deleteColumn: View
private var onLoadMore: OnLoadMore<Long>? = null
private val adapter by lazy { ColumnCardAdapter(presenter.getCards(), isOwner()) }
@ -119,6 +122,9 @@ class ProjectColumnFragment : BaseFragment<ProjectColumnMvp.View, ProjectColumnP
if (presenter.getCards().isEmpty() && !presenter.isApiCalled) {
presenter.onCallApi(1, column.id)
}
addCard.visibility = if(isOwner()) View.VISIBLE else View.GONE
deleteColumn.visibility = if(isOwner()) View.VISIBLE else View.GONE
editColumn.visibility = if(isOwner()) View.VISIBLE else View.GONE
}
override fun showProgress(@StringRes resId: Int) {
@ -143,7 +149,7 @@ class ProjectColumnFragment : BaseFragment<ProjectColumnMvp.View, ProjectColumnP
override fun onScrollTop(index: Int) {
super.onScrollTop(index)
recycler?.scrollToPosition(0)
recycler.scrollToPosition(0)
}
override fun onDestroyView() {

View File

@ -18,6 +18,7 @@ import com.fastaccess.helper.Bundler
import com.fastaccess.ui.adapter.FragmentsPagerAdapter
import com.fastaccess.ui.base.BaseActivity
import com.fastaccess.ui.modules.repos.RepoPagerActivity
import com.fastaccess.ui.modules.user.UserPagerActivity
import com.fastaccess.ui.widgets.CardsPagerTransformerBasic
/**
@ -76,12 +77,17 @@ class ProjectPagerActivity : BaseActivity<ProjectPagerMvp.View, ProjectPagerPres
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
return when (item?.itemId) {
android.R.id.home -> {
if (!presenter.login.isBlank() && !presenter.repoId.isBlank()) {
val nameParse = NameParser("")
nameParse.name = presenter.repoId
nameParse.username = presenter.login
nameParse.isEnterprise = isEnterprise
RepoPagerActivity.startRepoPager(this, nameParse)
val repoId = presenter.repoId
if (repoId != null && !repoId.isNullOrBlank()) {
if (!presenter.login.isBlank()) {
val nameParse = NameParser("")
nameParse.name = presenter.repoId
nameParse.username = presenter.login
nameParse.isEnterprise = isEnterprise
RepoPagerActivity.startRepoPager(this, nameParse)
}
} else if (!presenter.login.isBlank()) {
UserPagerActivity.startActivity(this, presenter.login, true, isEnterprise, 0)
}
finish()
true
@ -98,10 +104,12 @@ class ProjectPagerActivity : BaseActivity<ProjectPagerMvp.View, ProjectPagerPres
hideProgress()
}
pager.clipToPadding = false
val partialWidth = resources.getDimensionPixelSize(R.dimen.spacing_xs_large)
val pageMargin = resources.getDimensionPixelSize(R.dimen.spacing_normal)
val pagerPadding = partialWidth + pageMargin
pager.pageMargin = pageMargin
pager.setPageTransformer(true, CardsPagerTransformerBasic(4, 10))
pager.setPadding(pageMargin, pageMargin, pageMargin, pageMargin)
pager.setPadding(pagerPadding, pagerPadding, pagerPadding, pagerPadding)
if (savedInstanceState == null) {
presenter.onActivityCreated(intent)
@ -110,7 +118,11 @@ class ProjectPagerActivity : BaseActivity<ProjectPagerMvp.View, ProjectPagerPres
} else {
onInitPager(presenter.getColumns())
}
toolbar?.subtitle = "${presenter.login}/${presenter.repoId}"
if (presenter.repoId.isNullOrBlank()) {
toolbar?.subtitle = presenter.login
} else {
toolbar?.subtitle = "${presenter.login}/${presenter.repoId}"
}
}
override fun onDeletePage(model: ProjectColumnModel) {
@ -119,16 +131,17 @@ class ProjectPagerActivity : BaseActivity<ProjectPagerMvp.View, ProjectPagerPres
}
companion object {
fun startActivity(context: Context, login: String, repoId: String, projectId: Long) {
context.startActivity(getIntent(context, login, repoId, projectId))
fun startActivity(context: Context, login: String, repoId: String? = null, projectId: Long, isEnterprise: Boolean = false) {
context.startActivity(getIntent(context, login, repoId, projectId, isEnterprise))
}
fun getIntent(context: Context, login: String, repoId: String, projectId: Long): Intent {
fun getIntent(context: Context, login: String, repoId: String? = null, projectId: Long, isEnterprise: Boolean = false): Intent {
val intent = Intent(context, ProjectPagerActivity::class.java)
intent.putExtras(Bundler.start()
.put(BundleConstant.ID, projectId)
.put(BundleConstant.ITEM, repoId)
.put(BundleConstant.EXTRA, login)
.put(BundleConstant.IS_ENTERPRISE, isEnterprise)
.end())
return intent
}

View File

@ -19,7 +19,7 @@ class ProjectPagerPresenter : BasePresenter<ProjectPagerMvp.View>(), ProjectPage
private val columns = arrayListOf<ProjectColumnModel>()
@com.evernote.android.state.State var projectId: Long = -1
@com.evernote.android.state.State var repoId: String = ""
@com.evernote.android.state.State var repoId: String? = null
@com.evernote.android.state.State var login: String = ""
@com.evernote.android.state.State var viewerCanUpdate: Boolean = false
@ -27,23 +27,39 @@ class ProjectPagerPresenter : BasePresenter<ProjectPagerMvp.View>(), ProjectPage
override fun onRetrieveColumns() {
makeRestCall(Observable.zip(RestProvider.getProjectsService(isEnterprise).getProjectColumns(projectId),
RestProvider.getRepoService(isEnterprise).isCollaborator(login, repoId, Login.getUser().login),
BiFunction { items: Pageable<ProjectColumnModel>, response: Response<Boolean> ->
viewerCanUpdate = response.code() == 204
return@BiFunction items
})
.flatMap {
if (it.items != null) {
return@flatMap Observable.just(it.items)
}
return@flatMap Observable.just(listOf<ProjectColumnModel>())
},
{ t ->
columns.clear()
columns.addAll(t)
sendToView { it.onInitPager(columns) }
})
val repoId = repoId
if (repoId != null && !repoId.isNullOrBlank()) {
makeRestCall(Observable.zip(RestProvider.getProjectsService(isEnterprise).getProjectColumns(projectId),
RestProvider.getRepoService(isEnterprise).isCollaborator(login, repoId, Login.getUser().login),
BiFunction { items: Pageable<ProjectColumnModel>, response: Response<Boolean> ->
viewerCanUpdate = response.code() == 204
return@BiFunction items
})
.flatMap {
if (it.items != null) {
return@flatMap Observable.just(it.items)
}
return@flatMap Observable.just(listOf<ProjectColumnModel>())
},
{ t ->
columns.clear()
columns.addAll(t)
sendToView { it.onInitPager(columns) }
})
} else {
makeRestCall(RestProvider.getProjectsService(isEnterprise).getProjectColumns(projectId)
.flatMap {
if (it.items != null) {
return@flatMap Observable.just(it.items)
}
return@flatMap Observable.just(listOf<ProjectColumnModel>())
},
{ t ->
columns.clear()
columns.addAll(t)
sendToView { it.onInitPager(columns) }
})
}
}
override fun onActivityCreated(intent: Intent?) {

View File

@ -134,7 +134,7 @@ class RepoProjectFragment : BaseFragment<RepoProjectMvp.View, RepoProjectPresent
private fun getState(): IssueState = arguments.getSerializable(BundleConstant.EXTRA_TYPE) as IssueState
companion object {
fun newInstance(login: String, repoId: String, state: IssueState): RepoProjectFragment {
fun newInstance(login: String, repoId: String? = null, state: IssueState): RepoProjectFragment {
val fragment = RepoProjectFragment()
fragment.arguments = Bundler.start()
.put(BundleConstant.ID, repoId)

View File

@ -5,9 +5,12 @@ import android.view.View
import com.apollographql.apollo.rx2.Rx2Apollo
import com.fastaccess.data.dao.types.IssueState
import com.fastaccess.helper.BundleConstant
import com.fastaccess.helper.Logger
import com.fastaccess.provider.rest.ApolloProdivder
import com.fastaccess.ui.base.mvp.presenter.BasePresenter
import com.fastaccess.ui.modules.repos.projects.details.ProjectPagerActivity
import github.OrgProjectsClosedQuery
import github.OrgProjectsOpenQuery
import github.RepoProjectsClosedQuery
import github.RepoProjectsOpenQuery
import io.reactivex.Observable
@ -22,13 +25,13 @@ class RepoProjectPresenter : BasePresenter<RepoProjectMvp.View>(), RepoProjectMv
private var previousTotal: Int = 0
private var lastPage = Integer.MAX_VALUE
@com.evernote.android.state.State var login: String = ""
@com.evernote.android.state.State var repoId: String = ""
@com.evernote.android.state.State var repoId: String? = null
var count: Int = 0
val pages = arrayListOf<String>()
override fun onItemClick(position: Int, v: View, item: RepoProjectsOpenQuery.Node) {
item.databaseId()?.let {
ProjectPagerActivity.startActivity(v.context, login, repoId, it.toLong())
ProjectPagerActivity.startActivity(v.context, login, repoId, it.toLong(), isEnterprise)
}
}
@ -65,72 +68,152 @@ class RepoProjectPresenter : BasePresenter<RepoProjectMvp.View>(), RepoProjectMv
return false
}
currentPage = page
Logger.e(login)
val repoId = repoId
val apollo = ApolloProdivder.getApollo(isEnterprise)
if (parameter == IssueState.open) {
val query = RepoProjectsOpenQuery.builder()
.name(repoId)
.owner(login)
.page(getPage())
.build()
makeRestCall(Rx2Apollo.from(apollo.query(query))
.flatMap {
val list = arrayListOf<RepoProjectsOpenQuery.Node>()
it.data()?.repository()?.let {
it.projects().let {
pages.clear()
count = it.totalCount()
it.edges()?.let {
pages.addAll(it.map { it.cursor() })
}
it.nodes()?.let {
list.addAll(it)
}
}
}
return@flatMap Observable.just(list)
},
{
sendToView({ v ->
v.onNotifyAdapter(it, page)
if (page == 1) v.onChangeTotalCount(count)
})
})
} else {
val query = RepoProjectsClosedQuery.builder()
.name(repoId)
.owner(login)
.page(getPage())
.build()
makeRestCall(Rx2Apollo.from(apollo.query(query))
.flatMap {
val list = arrayListOf<RepoProjectsOpenQuery.Node>()
it.data()?.repository()?.let {
it.projects().let {
pages.clear()
count = it.totalCount()
it.edges()?.let {
pages.addAll(it.map { it.cursor() })
}
it.nodes()?.let {
val toConvert = arrayListOf<RepoProjectsOpenQuery.Node>()
it.onEach {
val columns = RepoProjectsOpenQuery.Columns(it.columns().__typename(), it.columns().totalCount())
val node = RepoProjectsOpenQuery.Node(it.__typename(), it.name(), it.number(), it.body(),
it.createdAt(), it.id(), it.viewerCanUpdate(), columns, it.databaseId())
toConvert.add(node)
if (repoId != null && !repoId.isNullOrBlank()) {
if (parameter == IssueState.open) {
val query = RepoProjectsOpenQuery.builder()
.name(repoId)
.owner(login)
.page(getPage())
.build()
makeRestCall(Rx2Apollo.from(apollo.query(query))
.flatMap {
val list = arrayListOf<RepoProjectsOpenQuery.Node>()
it.data()?.repository()?.let {
it.projects().let {
lastPage = if (it.pageInfo().hasNextPage()) Int.MAX_VALUE else 0
pages.clear()
count = it.totalCount()
it.edges()?.let {
pages.addAll(it.map { it.cursor() })
}
it.nodes()?.let {
list.addAll(it)
}
list.addAll(toConvert)
}
}
}
return@flatMap Observable.just(list)
},
{
sendToView({ v ->
v.onNotifyAdapter(it, page)
if (page == 1) v.onChangeTotalCount(count)
return@flatMap Observable.just(list)
},
{
sendToView({ v ->
v.onNotifyAdapter(it, page)
if (page == 1) v.onChangeTotalCount(count)
})
})
})
} else {
val query = RepoProjectsClosedQuery.builder()
.name(repoId)
.owner(login)
.page(getPage())
.build()
makeRestCall(Rx2Apollo.from(apollo.query(query))
.flatMap {
val list = arrayListOf<RepoProjectsOpenQuery.Node>()
it.data()?.repository()?.let {
it.projects().let {
lastPage = if (it.pageInfo().hasNextPage()) Int.MAX_VALUE else 0
pages.clear()
count = it.totalCount()
it.edges()?.let {
pages.addAll(it.map { it.cursor() })
}
it.nodes()?.let {
val toConvert = arrayListOf<RepoProjectsOpenQuery.Node>()
it.onEach {
val columns = RepoProjectsOpenQuery.Columns(it.columns().__typename(), it.columns().totalCount())
val node = RepoProjectsOpenQuery.Node(it.__typename(), it.name(), it.number(), it.body(),
it.createdAt(), it.id(), it.viewerCanUpdate(), columns, it.databaseId())
toConvert.add(node)
}
list.addAll(toConvert)
}
}
}
return@flatMap Observable.just(list)
},
{
sendToView({ v ->
v.onNotifyAdapter(it, page)
if (page == 1) v.onChangeTotalCount(count)
})
})
}
} else {
if (parameter == IssueState.open) {
val query = OrgProjectsOpenQuery.builder()
.owner(login)
.page(getPage())
.build()
makeRestCall(Rx2Apollo.from(apollo.query(query))
.flatMap {
val list = arrayListOf<RepoProjectsOpenQuery.Node>()
it.data()?.organization()?.let {
it.projects().let {
lastPage = if (it.pageInfo().hasNextPage()) Int.MAX_VALUE else 0
pages.clear()
count = it.totalCount()
it.edges()?.let {
pages.addAll(it.map { it.cursor() })
}
it.nodes()?.let {
val toConvert = arrayListOf<RepoProjectsOpenQuery.Node>()
it.onEach {
val columns = RepoProjectsOpenQuery.Columns(it.columns().__typename(), it.columns().totalCount())
val node = RepoProjectsOpenQuery.Node(it.__typename(), it.name(), it.number(), it.body(),
it.createdAt(), it.id(), it.viewerCanUpdate(), columns, it.databaseId())
toConvert.add(node)
}
list.addAll(toConvert)
}
}
}
return@flatMap Observable.just(list)
},
{
sendToView({ v ->
v.onNotifyAdapter(it, page)
if (page == 1) v.onChangeTotalCount(count)
})
})
} else {
val query = OrgProjectsClosedQuery.builder()
.owner(login)
.page(getPage())
.build()
makeRestCall(Rx2Apollo.from(apollo.query(query))
.flatMap {
val list = arrayListOf<RepoProjectsOpenQuery.Node>()
it.data()?.organization()?.let {
it.projects().let {
lastPage = if (it.pageInfo().hasNextPage()) Int.MAX_VALUE else 0
pages.clear()
count = it.totalCount()
it.edges()?.let {
pages.addAll(it.map { it.cursor() })
}
it.nodes()?.let {
val toConvert = arrayListOf<RepoProjectsOpenQuery.Node>()
it.onEach {
val columns = RepoProjectsOpenQuery.Columns(it.columns().__typename(), it.columns().totalCount())
val node = RepoProjectsOpenQuery.Node(it.__typename(), it.name(), it.number(), it.body(),
it.createdAt(), it.id(), it.viewerCanUpdate(), columns, it.databaseId())
toConvert.add(node)
}
list.addAll(toConvert)
}
}
}
return@flatMap Observable.just(list)
},
{
sendToView({ v ->
v.onNotifyAdapter(it, page)
if (page == 1) v.onChangeTotalCount(count)
})
})
}
}
return true
}

View File

@ -1,6 +1,8 @@
package com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.files;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -24,6 +26,7 @@ import com.fastaccess.ui.adapter.CommitFilesAdapter;
import com.fastaccess.ui.base.BaseFragment;
import com.fastaccess.ui.modules.main.premium.PremiumActivity;
import com.fastaccess.ui.modules.repos.issues.issue.details.IssuePagerMvp;
import com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.files.fullscreen.FullScreenFileChangeActivity;
import com.fastaccess.ui.modules.reviews.AddReviewDialogFragment;
import com.fastaccess.ui.widgets.FontTextView;
import com.fastaccess.ui.widgets.StateLayout;
@ -169,6 +172,10 @@ public class PullRequestFilesFragment extends BaseFragment<PullRequestFilesMvp.V
return onLoadMore;
}
@Override public void onOpenForResult(int position, @NonNull CommitFileChanges model) {
FullScreenFileChangeActivity.Companion.startActivityForResult(this, model, position);
}
@Override public void onRefresh() {
getPresenter().onCallApi(1, null);
}
@ -232,6 +239,23 @@ public class PullRequestFilesFragment extends BaseFragment<PullRequestFilesMvp.V
}
}
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == FullScreenFileChangeActivity.Companion.getFOR_RESULT_CODE() && data != null) {
List<CommentRequestModel> comments = data.getParcelableArrayListExtra(BundleConstant.ITEM);
if (comments != null && !comments.isEmpty()) {
if (viewCallback != null) {
for (CommentRequestModel comment : comments) {
viewCallback.onAddComment(comment);
}
showMessage(R.string.success, R.string.comments_added_successfully);
}
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void showReload() {
hideProgress();
stateLayout.showReload(adapter.getItemCount());

View File

@ -29,6 +29,8 @@ public interface PullRequestFilesMvp {
void onNotifyAdapter(@Nullable List<CommitFileChanges> items, int page);
@NonNull OnLoadMore getLoadMore();
void onOpenForResult(int position, @NonNull CommitFileChanges linesModel);
}
interface Presenter extends BaseMvp.FAPresenter,

View File

@ -104,7 +104,9 @@ class PullRequestFilesPresenter extends BasePresenter<PullRequestFilesMvp.View>
}
@Override public void onItemClick(int position, View v, CommitFileChanges model) {
if (v.getId() == R.id.open) {
if (v.getId() == R.id.patchList) {
sendToView(view -> view.onOpenForResult(position, model));
} else if (v.getId() == R.id.open) {
CommitFileModel item = model.getCommitFileModel();
PopupMenu popup = new PopupMenu(v.getContext(), v);
MenuInflater inflater = popup.getMenuInflater();

View File

@ -0,0 +1,168 @@
package com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.files.fullscreen
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.widget.SwipeRefreshLayout
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.TextView
import butterknife.BindView
import com.fastaccess.R
import com.fastaccess.data.dao.CommentRequestModel
import com.fastaccess.data.dao.CommitFileChanges
import com.fastaccess.data.dao.CommitLinesModel
import com.fastaccess.helper.BundleConstant
import com.fastaccess.helper.Bundler
import com.fastaccess.helper.PrefGetter
import com.fastaccess.ui.adapter.CommitLinesAdapter
import com.fastaccess.ui.base.BaseActivity
import com.fastaccess.ui.modules.main.premium.PremiumActivity
import com.fastaccess.ui.modules.reviews.AddReviewDialogFragment
import com.fastaccess.ui.widgets.StateLayout
import com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView
import com.fastaccess.ui.widgets.recyclerview.scroll.RecyclerViewFastScroller
/**
* Created by Hashemsergani on 24.09.17.
*/
class FullScreenFileChangeActivity : BaseActivity<FullScreenFileChangeMvp.View, FullScreenFileChangePresenter>(), FullScreenFileChangeMvp.View {
@BindView(R.id.recycler) lateinit var recycler: DynamicRecyclerView
@BindView(R.id.refresh) lateinit var refresh: SwipeRefreshLayout
@BindView(R.id.stateLayout) lateinit var stateLayout: StateLayout
@BindView(R.id.fastScroller) lateinit var fastScroller: RecyclerViewFastScroller
@BindView(R.id.changes) lateinit var changes: TextView
@BindView(R.id.deletion) lateinit var deletion: TextView
@BindView(R.id.addition) lateinit var addition: TextView
val commentList = arrayListOf<CommentRequestModel>()
private val adapter by lazy { CommitLinesAdapter(arrayListOf(), this) }
override fun layout(): Int = R.layout.full_screen_file_changes_layout
override fun isTransparent(): Boolean = false
override fun canBack(): Boolean = true
override fun isSecured(): Boolean = false
override fun providePresenter(): FullScreenFileChangePresenter = FullScreenFileChangePresenter()
override fun onNotifyAdapter(model: CommitLinesModel) {
adapter.addItem(model)
}
override fun showMessage(titleRes: Int, msgRes: Int) {
hideProgress()
super.showMessage(titleRes, msgRes)
}
override fun showMessage(titleRes: String, msgRes: String) {
hideProgress()
super.showMessage(titleRes, msgRes)
}
override fun showErrorMessage(msgRes: String) {
hideProgress()
super.showErrorMessage(msgRes)
}
override fun showProgress(resId: Int) {
stateLayout.showProgress()
refresh.isRefreshing = true
}
override fun hideProgress() {
stateLayout.hideProgress()
refresh.isRefreshing = false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
refresh.isEnabled = false
recycler.adapter = adapter
val padding = resources.getDimensionPixelSize(R.dimen.spacing_normal)
recycler.setPadding(padding, 0, padding, 0)
fastScroller.attachRecyclerView(recycler)
presenter.onLoad(intent)
presenter.model?.let { model ->
title = Uri.parse(model.commitFileModel.filename).lastPathSegment
addition.text = model.commitFileModel?.additions.toString()
deletion.text = model.commitFileModel?.deletions.toString()
changes.text = model.commitFileModel?.changes.toString()
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.done_menu, menu)
menu?.findItem(R.id.submit)?.setIcon(R.drawable.ic_done)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
return when (item?.itemId) {
R.id.submit -> {
val intent = Intent()
intent.putExtras(Bundler.start().putParcelableArrayList(BundleConstant.ITEM, commentList).end())
setResult(Activity.RESULT_OK, intent)
finish()
true
}
else -> super.onOptionsItemSelected(item)
}
}
override fun onItemClick(position: Int, v: View, item: CommitLinesModel) {
if (item.text.startsWith("@@")) return
val commit = presenter.model?.commitFileModel ?: return
if (PrefGetter.isProEnabled()) {
AddReviewDialogFragment.newInstance(item, Bundler.start()
.put(BundleConstant.ITEM, commit.filename)
.put(BundleConstant.EXTRA_TWO, presenter.position)
.put(BundleConstant.EXTRA_THREE, position)
.end())
.show(supportFragmentManager, "AddReviewDialogFragment")
} else {
PremiumActivity.startActivity(this)
}
}
override fun onItemLongClick(position: Int, v: View?, item: CommitLinesModel?) {
}
override fun onCommentAdded(comment: String, item: CommitLinesModel, bundle: Bundle?) {
if (bundle != null) {
val path = bundle.getString(BundleConstant.ITEM) ?: return
val commentRequestModel = CommentRequestModel()
commentRequestModel.body = comment
commentRequestModel.path = path
commentRequestModel.position = item.position
commentList.add(commentRequestModel)
val childPosition = bundle.getInt(BundleConstant.EXTRA_THREE)
val current = adapter.getItem(childPosition)
if (current != null) {
current.isHasCommentedOn = true
adapter.swapItem(current, childPosition)
}
}
}
companion object {
val FOR_RESULT_CODE = 1002
fun startActivityForResult(fragment: Fragment, model: CommitFileChanges, position: Int) {
val intent = Intent(fragment.context, FullScreenFileChangeActivity::class.java)
intent.putExtras(Bundler.start()
.put(BundleConstant.EXTRA, model)
.put(BundleConstant.ITEM, position)
.end())
fragment.startActivityForResult(intent, FOR_RESULT_CODE)
}
}
}

View File

@ -0,0 +1,21 @@
package com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.files.fullscreen
import android.content.Intent
import com.fastaccess.data.dao.CommitLinesModel
import com.fastaccess.ui.base.mvp.BaseMvp
import com.fastaccess.ui.modules.reviews.callback.ReviewCommentListener
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
/**
* Created by Hashemsergani on 24.09.17.
*/
interface FullScreenFileChangeMvp {
interface View : BaseMvp.FAView, BaseViewHolder.OnItemClickListener<CommitLinesModel>, ReviewCommentListener {
fun onNotifyAdapter(model: CommitLinesModel)
}
interface Presenter {
fun onLoad(intent: Intent)
}
}

View File

@ -0,0 +1,37 @@
package com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.files.fullscreen
import android.content.Intent
import com.fastaccess.data.dao.CommitFileChanges
import com.fastaccess.helper.BundleConstant
import com.fastaccess.helper.RxHelper
import com.fastaccess.ui.base.mvp.presenter.BasePresenter
import io.reactivex.Observable
/**
* Created by Hashemsergani on 24.09.17.
*/
class FullScreenFileChangePresenter : BasePresenter<FullScreenFileChangeMvp.View>(), FullScreenFileChangeMvp.Presenter {
var model: CommitFileChanges? = null
var position: Int = -1
override fun onLoad(intent: Intent) {
intent.extras?.let {
position = it.getInt(BundleConstant.ITEM)
model = it.getParcelable(BundleConstant.EXTRA)
}
model?.let {
manageDisposable(RxHelper.getObservable(Observable.fromIterable(it.linesModel))
.doOnSubscribe({ sendToView { it.showProgress(0) } })
.flatMap { Observable.just(it) }
.subscribe
({
sendToView { v -> v.onNotifyAdapter(it) }
}, {
onError(it)
}, {
sendToView { it.hideProgress() }
}))
}
}
}

View File

@ -39,10 +39,10 @@ class AddReviewDialogFragment : BaseDialogFragment<BaseMvp.FAView, BasePresenter
override fun onAttach(context: Context?) {
super.onAttach(context)
if (parentFragment is ReviewCommentListener) {
commentCallback = parentFragment as ReviewCommentListener
commentCallback = if (parentFragment is ReviewCommentListener) {
parentFragment as ReviewCommentListener
} else {
commentCallback = context as ReviewCommentListener
context as ReviewCommentListener
}
}

View File

@ -123,7 +123,7 @@ class ReviewChangesActivity : BaseDialogFragment<ReviewChangesMvp.View, ReviewCh
override fun onClearEditText() {
commentEditorFragment?.let {
it.commentText?.let {
it.commentText.let {
it.text = null
}
}

View File

@ -41,7 +41,7 @@ class SearchPresenter extends BasePresenter<SearchMvp.View> implements SearchMvp
}
@Override public void onSearchClicked(@NonNull ViewPager viewPager, @NonNull AutoCompleteTextView editText) {
boolean isEmpty = InputHelper.isEmpty(editText) || InputHelper.toString(editText).length() < 3;
boolean isEmpty = InputHelper.isEmpty(editText) || InputHelper.toString(editText).length() < 2;
editText.setError(isEmpty ? editText.getResources().getString(R.string.minimum_three_chars) : null);
if (!isEmpty) {
editText.dismissDropDown();

View File

@ -19,7 +19,7 @@ public class SearchFilePresenter extends BasePresenter<SearchFileMvp.View> imple
}
@Override public void onSearchClicked(@NonNull FontEditText editText, boolean inPath) {
boolean isEmpty = InputHelper.isEmpty(editText) || InputHelper.toString(editText).length() < 3;
boolean isEmpty = InputHelper.isEmpty(editText) || InputHelper.toString(editText).length() < 2;
editText.setError(isEmpty ? editText.getResources().getString(R.string.minimum_three_chars) : null);
if (!isEmpty) {
AppHelper.hideKeyboard(editText);

View File

@ -35,10 +35,10 @@ class NotificationSoundBottomSheet : BaseMvpBottomSheetDialogFragment<Notificati
override fun onAttach(context: Context?) {
super.onAttach(context)
if (parentFragment is NotificationSoundMvp.NotificationSoundListener) {
listener = parentFragment as NotificationSoundMvp.NotificationSoundListener
listener = if (parentFragment is NotificationSoundMvp.NotificationSoundListener) {
parentFragment as NotificationSoundMvp.NotificationSoundListener
} else {
listener = context as NotificationSoundMvp.NotificationSoundListener
context as NotificationSoundMvp.NotificationSoundListener
}
}

View File

@ -130,17 +130,17 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
return when (item?.itemId) {
R.id.menu -> {
drawerLayout.openDrawer(Gravity.END)
return true
true
}
android.R.id.home -> {
startActivity(Intent(this, MainActivity::class.java))
finish()
return true
true
}
else -> return super.onOptionsItemSelected(item)
else -> super.onOptionsItemSelected(item)
}
}
@ -156,9 +156,9 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
}
private fun onItemClicked(item: MenuItem?): Boolean {
when (item?.title.toString()) {
"All Language" -> selectedTitle = ""
else -> selectedTitle = item?.title.toString()
selectedTitle = when (item?.title.toString()) {
"All Language" -> ""
else -> item?.title.toString()
}
Logger.e(selectedTitle)
setValues()
@ -176,11 +176,11 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
}
private fun getSince(): String {
when {
daily.isSelected -> return "daily"
weekly.isSelected -> return "weekly"
monthly.isSelected -> return "monthly"
else -> return "daily"
return when {
daily.isSelected -> "daily"
weekly.isSelected -> "weekly"
monthly.isSelected -> "monthly"
else -> "daily"
}
}

View File

@ -9,6 +9,7 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.view.View;
import android.view.Window;
import com.fastaccess.R;
import com.fastaccess.helper.Bundler;
@ -23,6 +24,10 @@ import net.grandcentrix.thirtyinch.TiPresenter;
public class ProgressDialogFragment extends BaseDialogFragment {
public ProgressDialogFragment() {
suppressAnimation = true;
}
public static final String TAG = ProgressDialogFragment.class.getSimpleName();
@NonNull public static ProgressDialogFragment newInstance(@NonNull Resources resources, @StringRes int msgId, boolean isCancelable) {
@ -50,7 +55,11 @@ public class ProgressDialogFragment extends BaseDialogFragment {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setCancelable(false);
setCancelable(false);
if (dialog.getWindow() != null) dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
window.setDimAmount(0);
}
return dialog;
}

View File

@ -33,7 +33,7 @@ class MarkDownLayout : LinearLayout {
}
var markdownListener: MarkdownListener? = null
var selectionIndex = 0
@BindView(R.id.editorIconsHolder) lateinit var editorIconsHolder: HorizontalScrollView
@BindView(R.id.addEmoji) lateinit var addEmojiView: View
@ -54,19 +54,20 @@ class MarkDownLayout : LinearLayout {
super.onDetachedFromWindow()
}
@OnClick(R.id.view) internal fun onViewMarkDown() {
@OnClick(R.id.view) fun onViewMarkDown() {
markdownListener?.let {
it.getEditText().let { editText ->
TransitionManager.beginDelayedTransition(this)
if (editText.isEnabled && !InputHelper.isEmpty(editText)) {
editText.isEnabled = false
selectionIndex = editText.selectionEnd
MarkDownProvider.setMdText(editText, InputHelper.toString(editText))
editorIconsHolder.visibility = View.INVISIBLE
addEmojiView.visibility = View.INVISIBLE
ViewHelper.hideKeyboard(editText)
} else {
editText.setText(it.getSavedText())
editText.setSelection(editText.text.length)
editText.setSelection(selectionIndex)
editText.isEnabled = true
editorIconsHolder.visibility = View.VISIBLE
addEmojiView.visibility = View.VISIBLE
@ -87,9 +88,9 @@ class MarkDownLayout : LinearLayout {
Snackbar.make(this, R.string.error_highlighting_editor, Snackbar.LENGTH_SHORT).show()
} else {
when {
v.id == R.id.link -> EditorLinkImageDialogFragment.newInstance(true)
v.id == R.id.link -> EditorLinkImageDialogFragment.newInstance(true, getSelectedText())
.show(it.fragmentManager(), "EditorLinkImageDialogFragment")
v.id == R.id.image -> EditorLinkImageDialogFragment.newInstance(false)
v.id == R.id.image -> EditorLinkImageDialogFragment.newInstance(false, getSelectedText())
.show(it.fragmentManager(), "EditorLinkImageDialogFragment")
v.id == R.id.addEmoji -> {
ViewHelper.hideKeyboard(it.getEditText())
@ -119,8 +120,6 @@ class MarkDownLayout : LinearLayout {
R.id.header -> MarkDownProvider.addDivider(editText)
R.id.code -> MarkDownProvider.addCode(editText)
R.id.quote -> MarkDownProvider.addQuote(editText)
R.id.link -> MarkDownProvider.addLink(editText)
R.id.image -> MarkDownProvider.addPhoto(editText)
R.id.checkbox -> MarkDownProvider.addList(editText, "- [x]")
R.id.unCheckbox -> MarkDownProvider.addList(editText, "- [ ]")
R.id.inlineCode -> MarkDownProvider.addInlinleCode(editText)
@ -162,4 +161,15 @@ class MarkDownLayout : LinearLayout {
}
}
}
private fun getSelectedText(): String? {
markdownListener?.getEditText()?.let {
if (!it.text.toString().isBlank()) {
val selectionStart = it.selectionStart
val selectionEnd = it.selectionEnd
return it.text.toString().substring(selectionStart, selectionEnd)
}
}
return null
}
}

View File

@ -8,7 +8,7 @@ import android.support.annotation.NonNull;
public class PrettifyHelper {
@NonNull private static String getHtmlContent(@NonNull String css, @NonNull String text, @NonNull boolean wrap, boolean isDark) {
@NonNull private static String getHtmlContent(@NonNull String css, @NonNull String text, boolean wrap, boolean isDark) {
return "<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +

View File

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
@ -83,18 +85,154 @@
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/submit"
android:layout_width="wrap_content"
<LinearLayout
android:id="@+id/issueMiscLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_send"
android:tint="@color/white"/>
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<LinearLayout
android:id="@+id/assigneeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/addAssignee"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:drawableEnd="@drawable/ic_add"
android:paddingBottom="@dimen/spacing_normal"
android:paddingTop="@dimen/spacing_normal"
android:text="@string/assignee"/>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_xs_large"
app:cardBackgroundColor="?card_background"
app:contentPaddingBottom="@dimen/spacing_normal"
app:contentPaddingLeft="@dimen/spacing_xs_large"
app:contentPaddingRight="@dimen/spacing_xs_large"
app:contentPaddingTop="@dimen/spacing_normal">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/assignee"
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Username"/>
</android.support.v7.widget.CardView>
</LinearLayout>
<LinearLayout
android:id="@+id/labelsLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/addLabels"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:drawableEnd="@drawable/ic_add"
android:paddingBottom="@dimen/spacing_normal"
android:paddingTop="@dimen/spacing_normal"
android:text="@string/labels"/>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_xs_large"
app:cardBackgroundColor="?card_background"
app:contentPaddingBottom="@dimen/spacing_normal"
app:contentPaddingLeft="@dimen/spacing_xs_large"
app:contentPaddingRight="@dimen/spacing_xs_large"
app:contentPaddingTop="@dimen/spacing_normal">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/labels"
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Label 1"/>
</android.support.v7.widget.CardView>
</LinearLayout>
<LinearLayout
android:id="@+id/milestoneLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/addMilestone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:drawableEnd="@drawable/ic_add"
android:paddingBottom="@dimen/spacing_normal"
android:paddingTop="@dimen/spacing_normal"
android:text="@string/milestone"/>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_xs_large"
app:cardBackgroundColor="?card_background"
app:contentPaddingBottom="@dimen/spacing_normal"
app:contentPaddingLeft="@dimen/spacing_xs_large"
app:contentPaddingRight="@dimen/spacing_xs_large"
app:contentPaddingTop="@dimen/spacing_normal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/milestoneTitle"
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Label 1"/>
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/milestoneDescription"
style="@style/TextAppearance.AppCompat.Subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/spacing_normal"
android:paddingTop="@dimen/spacing_normal"
android:visibility="gone"
tools:text="Label 1"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_send"
android:tint="@color/white"/>
<include layout="@layout/add_banner_layout"/>
</LinearLayout>

View File

@ -51,7 +51,8 @@
android:background="@color/transparent"
android:hint="@string/search"
android:paddingEnd="@dimen/spacing_xs_large"
android:paddingStart="@dimen/spacing_xs_large"/>
android:paddingStart="@dimen/spacing_xs_large"
android:singleLine="true"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?android:toolbarStyle">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:theme="?android:toolbarStyle"
app:layout_scrollFlags="scroll|enterAlways"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/bottom_border"
android:gravity="center"
android:orientation="horizontal"
android:padding="@dimen/spacing_normal">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/changes"
style="@style/TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|end"
android:layout_marginEnd="@dimen/spacing_xs_large"
android:background="?selectableItemBackgroundBorderless"
android:drawablePadding="@dimen/spacing_micro"
android:drawableTop="@drawable/ic_file_multi"
android:gravity="center"
tools:text="100"/>
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/addition"
style="@style/TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|end"
android:layout_marginEnd="@dimen/spacing_xs_large"
android:background="?selectableItemBackgroundBorderless"
android:drawablePadding="@dimen/spacing_micro"
android:drawableTop="@drawable/ic_add"
android:gravity="center"
android:scaleType="centerCrop"
tools:text="100"/>
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/deletion"
style="@style/TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|end"
android:background="?selectableItemBackgroundBorderless"
android:drawablePadding="@dimen/spacing_micro"
android:drawableTop="@drawable/ic_clear"
android:gravity="center"
tools:text="100"/>
</LinearLayout>
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/scroll_behavior">
<include layout="@layout/vertical_refresh_list"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>

View File

@ -193,8 +193,6 @@
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/spacing_normal"
android:paddingTop="@dimen/spacing_normal"
tools:text="Label 1"/>
<com.fastaccess.ui.widgets.FontTextView
@ -214,9 +212,9 @@
<LinearLayout
android:id="@+id/commentSection"
android:layout_width="match_parent"
android:layout_marginBottom="@dimen/spacing_normal"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginBottom="@dimen/spacing_normal"
android:baselineAligned="false"
android:orientation="horizontal">

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bottom_border"
android:paddingBottom="@dimen/spacing_xs_large"
android:paddingTop="@dimen/spacing_xs_large">
<com.fastaccess.ui.widgets.FontTextView
style="@style/TextAppearance.AppCompat.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingEnd="@dimen/spacing_xs_large"
android:paddingStart="@dimen/spacing_xs_large"
android:text="@string/please_read"
android:textColor="@color/material_red_700"/>
</FrameLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/description"
style="@style/TextAppearance.AppCompat.Small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="web"
android:padding="@dimen/spacing_xs_large"
tools:text="@string/fasthub_faq_description"/>
<com.fastaccess.ui.widgets.FontButton
android:id="@+id/done"
style="@style/Widget.AppCompat.ButtonBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:text="@string/done"
android:textColor="@color/material_red_700"/>
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@ -4,7 +4,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="?colorPrimary">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
@ -22,76 +23,63 @@
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<android.support.v7.widget.CardView
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="@dimen/spacing_micro"
app:cardBackgroundColor="?android:colorAccent"
app:cardCornerRadius="2dp"
android:orientation="vertical"
android:paddingBottom="@dimen/spacing_normal"
android:paddingEnd="@dimen/spacing_xs_large"
android:paddingStart="@dimen/spacing_xs_large"
android:paddingTop="@dimen/spacing_normal"
app:layout_collapseMode="parallax">
<LinearLayout
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/columnName"
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center"
android:ellipsize="marquee"
android:maxLines="3"
android:paddingBottom="@dimen/spacing_normal"
android:paddingEnd="@dimen/spacing_xs_large"
android:paddingStart="@dimen/spacing_xs_large"
android:paddingTop="@dimen/spacing_normal">
android:paddingTop="@dimen/spacing_normal"
tools:text="One must need the visitor in order to study the lord of great awareness."/>
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/columnName"
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="match_parent"
<LinearLayout
android:id="@+id/editColumnHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:orientation="horizontal">
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/editColumn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="marquee"
android:maxLines="3"
android:padding="@dimen/spacing_xs_large"
android:textColor="@color/white"
tools:text="One must need the visitor in order to study the lord of great awareness."/>
android:background="?selectableItemBackgroundBorderless"
android:padding="@dimen/spacing_micro"
android:src="@drawable/ic_edit"/>
<LinearLayout
android:id="@+id/editColumnHolder"
android:layout_width="match_parent"
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/addCard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:orientation="horizontal">
android:layout_marginEnd="@dimen/spacing_xs_large"
android:layout_marginStart="@dimen/spacing_xs_large"
android:background="?selectableItemBackgroundBorderless"
android:padding="@dimen/spacing_micro"
android:src="@drawable/ic_add"/>
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/editColumn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:padding="@dimen/spacing_micro"
android:src="@drawable/ic_edit"
android:tint="@color/white"/>
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/deleteColumn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:padding="@dimen/spacing_micro"
android:src="@drawable/ic_trash"/>
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/addCard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_xs_large"
android:layout_marginStart="@dimen/spacing_xs_large"
android:background="?selectableItemBackgroundBorderless"
android:padding="@dimen/spacing_micro"
android:src="@drawable/ic_add"
android:tint="@color/white"/>
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/deleteColumn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:padding="@dimen/spacing_micro"
android:src="@drawable/ic_trash"
android:tint="@color/white"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

View File

@ -5,9 +5,13 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_micro"
android:layout_marginBottom="@dimen/spacing_micro"
android:layout_marginEnd="@dimen/grid_spacing"
android:layout_marginStart="@dimen/grid_spacing"
android:layout_marginTop="@dimen/grid_spacing"
android:foreground="?android:selectableItemBackground"
app:cardBackgroundColor="?card_background"
app:cardCornerRadius="@dimen/grid_spacing"
app:contentPaddingBottom="@dimen/spacing_normal"
app:contentPaddingLeft="@dimen/spacing_xs_large"
app:contentPaddingTop="@dimen/spacing_normal">

View File

@ -1,134 +1,163 @@
<?xml version="1.0" encoding="utf-8"?>
<com.fastaccess.ui.widgets.ForegroundRelativeLayout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_normal"
android:layout_marginEnd="@dimen/grid_spacing"
android:layout_marginStart="@dimen/grid_spacing"
android:layout_marginTop="@dimen/grid_spacing"
android:background="?card_background"
android:paddingBottom="@dimen/spacing_normal"
android:paddingTop="@dimen/spacing_normal"
tools:ignore="RtlSymmetry">
android:orientation="vertical">
<LinearLayout
<com.fastaccess.ui.widgets.ForegroundRelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:layout_marginBottom="@dimen/spacing_normal"
android:layout_marginEnd="@dimen/grid_spacing"
android:layout_marginStart="@dimen/grid_spacing"
android:layout_marginTop="@dimen/grid_spacing"
android:background="?card_background"
android:paddingBottom="@dimen/spacing_normal"
android:paddingTop="@dimen/spacing_normal"
tools:ignore="RtlSymmetry">
<LinearLayout
android:id="@+id/toggleHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_micro"
android:orientation="horizontal">
<com.fastaccess.ui.widgets.AvatarLayout
android:id="@+id/avatarView"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/avatar_margin_end"
android:layout_marginStart="@dimen/avatar_margin"/>
android:orientation="vertical">
<LinearLayout
android:layout_width="0dp"
android:id="@+id/toggleHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/spacing_normal"
android:layout_weight="1"
android:orientation="vertical">
android:layout_marginEnd="@dimen/spacing_micro"
android:orientation="horizontal">
<com.fastaccess.ui.widgets.AvatarLayout
android:id="@+id/avatarView"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/avatar_margin_end"
android:layout_marginStart="@dimen/avatar_margin"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:layout_gravity="center"
android:layout_marginEnd="@dimen/spacing_normal"
android:layout_weight="1"
android:orientation="vertical">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/name"
style="@style/TextAppearance.AppCompat.Small"
android:layout_width="0dp"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorPrimary"
tools:text="When one acquires"/>
android:orientation="horizontal">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/name"
style="@style/TextAppearance.AppCompat.Small"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorPrimary"
tools:text="When one acquires"/>
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/date"
style="@style/TextAppearance.AppCompat.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxLines="1"
android:textColor="?android:attr/textColorSecondary"
tools:text="50 minutes"/>
</LinearLayout>
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/date"
style="@style/TextAppearance.AppCompat.Caption"
android:layout_width="wrap_content"
android:id="@+id/owner"
style="@style/TextAppearance.AppCompat.Small"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxLines="1"
android:textColor="?android:attr/textColorSecondary"
tools:text="50 minutes"/>
android:visibility="gone"
tools:text="@string/owner"
tools:visibility="visible"/>
</LinearLayout>
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/owner"
style="@style/TextAppearance.AppCompat.Small"
android:layout_width="match_parent"
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxLines="1"
android:textColor="?android:attr/textColorSecondary"
android:visibility="gone"
tools:text="@string/owner"
tools:visibility="visible"/>
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/options"
android:padding="@dimen/spacing_micro"
android:src="@drawable/ic_add_emoji"/>
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/commentMenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/options"
android:padding="@dimen/spacing_micro"
android:src="@drawable/ic_overflow"/>
</LinearLayout>
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/options"
android:padding="@dimen/spacing_micro"
android:src="@drawable/ic_add_emoji"/>
<include layout="@layout/comments_dropdown_layout"/>
<com.fastaccess.ui.widgets.ForegroundImageView
android:id="@+id/commentMenu"
android:layout_width="wrap_content"
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/options"
android:padding="@dimen/spacing_micro"
android:src="@drawable/ic_overflow"/>
android:layout_marginBottom="@dimen/spacing_micro"
android:layout_marginEnd="@dimen/spacing_xs_large"
android:layout_marginStart="@dimen/spacing_xs_large"
android:layout_marginTop="@dimen/spacing_micro"
android:textIsSelectable="true"/>
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/reactionsText"
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_xs_large"
android:layout_marginStart="@dimen/avatar_margin"
android:layout_marginTop="@dimen/spacing_micro"
android:gravity="start"
android:visibility="gone"
tools:ignore="RtlSymmetry"
tools:text="U+1F602"
tools:visibility="visible"/>
</LinearLayout>
<include layout="@layout/comments_dropdown_layout"/>
</com.fastaccess.ui.widgets.ForegroundRelativeLayout>
<LinearLayout
android:id="@+id/labelsHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_normal"
android:layout_marginEnd="@dimen/grid_spacing"
android:layout_marginStart="@dimen/grid_spacing"
android:layout_marginTop="@dimen/spacing_normal"
android:background="?card_background"
android:paddingBottom="@dimen/spacing_normal"
android:paddingTop="@dimen/spacing_normal"
android:visibility="gone"
tools:visibility="visible">
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/comment"
android:id="@+id/labels"
style="@style/TextAppearance.AppCompat.Caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_micro"
android:layout_marginEnd="@dimen/spacing_xs_large"
android:layout_marginStart="@dimen/spacing_xs_large"
android:layout_marginTop="@dimen/spacing_micro"
android:textIsSelectable="true"/>
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/reactionsText"
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_xs_large"
android:layout_marginStart="@dimen/avatar_margin"
android:layout_marginTop="@dimen/spacing_micro"
android:gravity="start"
android:visibility="gone"
tools:ignore="RtlSymmetry"
tools:text="U+1F602"
tools:visibility="visible"/>
android:gravity="center"/>
</LinearLayout>
</com.fastaccess.ui.widgets.ForegroundRelativeLayout>
</LinearLayout>

View File

@ -77,6 +77,7 @@
android:gravity="center|start"
android:paddingBottom="@dimen/spacing_xs_large"
android:paddingTop="@dimen/spacing_xs_large"
android:visibility="gone"
tools:text="Cum classis nocere"/>
@ -92,6 +93,7 @@
android:gravity="center|start"
android:paddingBottom="@dimen/spacing_xs_large"
android:paddingTop="@dimen/spacing_xs_large"
android:visibility="gone"
tools:text="Cum classis nocere"/>
<com.fastaccess.ui.widgets.FontTextView
@ -106,6 +108,7 @@
android:gravity="center|start"
android:paddingBottom="@dimen/spacing_xs_large"
android:paddingTop="@dimen/spacing_xs_large"
android:visibility="gone"
tools:text="Cum classis nocere"/>
@ -120,8 +123,25 @@
android:gravity="center|start"
android:paddingBottom="@dimen/spacing_xs_large"
android:paddingTop="@dimen/spacing_xs_large"
android:visibility="gone"
tools:text="Cum classis nocere"/>
<com.fastaccess.ui.widgets.FontTextView
android:id="@+id/projects"
style="@style/Base.TextAppearance.AppCompat.Subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/top_border"
android:drawablePadding="@dimen/spacing_xs_large"
android:drawableStart="@drawable/ic_project"
android:gravity="center|start"
android:paddingBottom="@dimen/spacing_xs_large"
android:paddingTop="@dimen/spacing_xs_large"
android:text="@string/projects"
android:textColor="?colorAccent"
android:visibility="gone"
app:drawableColor="?colorAccent"/>
</LinearLayout>
</android.support.v7.widget.CardView>

View File

@ -55,6 +55,10 @@
android:id="@+id/reportBug"
android:icon="@drawable/ic_bug"
android:title="@string/report_issue"/>
<item
android:id="@+id/faq"
android:icon="@drawable/ic_info"
android:title="@string/faq"/>
<item
android:id="@+id/settings"
android:icon="@drawable/ic_settings"

View File

@ -8,58 +8,32 @@
<body id="preview">
<h2><a id="FastHub_changelog_0"></a>FastHub changelog
</h2>
<h3><a id="Version__420_Create_Edit__Delete_files_make_Commits_2"></a>Version 4.2.0 (Create, Edit &amp; Delete files (make Commits))
<h3><a id="Version__420_Create_Edit__Delete_files_make_Commits_2"></a>Version 4.4.1 (Org Project Columns and Cards)
</h3>
<blockquote>
<p>Reporting Issues or Feature Requests in Google Play review section, will be ignored or might even get your account to be blocked from
FastHub. You are using an app for GitHub, which provides a proper way to report issues.
<br>
Please report the issues in FastHub repo instead, by opening the Drawer Menu, click about and click “Report an Issue”<strong>PLEASE
USE IT</strong>.
<p>Please report the issues in FastHub repo instead, by opening the Drawer Menu and clicking on “Report an Issue”<strong>
PLEASE USE IT</strong>.
</p>
</blockquote>
<h4><a id="Bugs__Enhancements__new_Features_320_7"></a>Bugs , Enhancements &amp; new Features (3.2.0)
<h4><a id="Bugs__Enhancements__new_Features_320_7"></a>Bugs , Enhancements &amp; new Features (4.4.1)
</h4>
<ul>
<li>(New) Make commits on repos from FastHub (this only applies for repo owners so far).
<strong>PRO</strong>
</li>
<li>(New) Long pressing files/directories will open up their Commit/Git History.</li>
<li>(New) Indicates PR review line has a comment.</li>
<li>(New) Showing number of addition, deletion &amp; files in PR files tab.</li>
<li>(New) Untoggle MD rendering to see their actual code.</li>
<li>(New) Settings option to disable Animations in FastHub.</li>
<li>(New) Copy SHA from Commit.</li>
<li>(New) Forks, Watchers &amp; Stargazers links handling.</li>
<li>(Enhancement) Loading larger number of comments per page.</li>
<li>(Enhancement) Hide fab while scrolling in Issues &amp; PR tab.</li>
<li>(Fix) PR Status where it got somehow broken in previous release.</li>
<li>(Fix) A text under PR status will indicates if the PR is mergable or not.</li>
<li>(Fix) Tagging users in full screen editor.</li>
<li>(Fix) Comments text selection where sometime they arent selectable.</li>
<li>(Fix) PR Review footer is invisible in (4.1.0).</li>
<li>(Fix) Cursor position after inserting emoji, links &amp; images.</li>
<li>(Fix) Teal customized accent was displayed as green.</li>
<li>(Fix) Some crashes from the crash report.</li>
<li>(New 4.4.1) Add Labels, Assignees & Milestone when creating/editing Issue</li>
<li>(New) Improvements to handle Students PRO.</li>
<li>(New) Org Project Columns & Cards (Edit, Create & Delete)</li>
<li>(New) Displaying Labels under Issue/Pr description.</li>
<li>(Enhancement) Removal of PR review limit.</li>
<li>(Enhancement) Selected text will be taken in consideration when adding Image/Link.</li>
<li>(Enhancement) Removed Loading background.</li>
<li>(Enhancement) More markdown enhancement.</li>
<li>(Fix) Lots of bug fixes.</li>
<li>There are more stuff are not mentioned, find them out :stuck_out_tongue:</li>
<li>There are more stuff are not mentioned, find them out ;).</li>
</ul>
<h3><a id="What_left_in_FastHub_29"></a>What left in FastHub?
</h3>
<blockquote>
<p>
<strong>So far, FastHub has implemented almost all the features of GitHub, besides for<strong>Project Cards</strong>. Hopefully in the
next release FastHub will include that. The following releases will mainly be bug fixes or if a major feature is implemented.
</strong>
</p>
</blockquote>
<h3><a id="How_old_is_FastHub_now_33"></a>How old is FastHub now?
</h3>
<blockquote>
<p>
<strong>FastHub is now 5 months &amp; a week old. Since v1.0.0 it has really grow with each and every release. The only way this was
possible, was due to the community helping out either via reporting bugs, feature requests or even give hand to fix things or
implement things in the app. Im really grateful for having such a great community. Thank you guys!
<strong>So far, FastHub has implemented all the features of GitHub, I'll continue to fix bugs, implement feature requests if any!.
</strong>
</p>
</blockquote>

View File

@ -399,6 +399,62 @@
<string name="sound_chooser_title">Benachrichtigungs Ton auswählen</string>
<string name="disable_auto_gif_summary">Deaktiviere automatische wiedergabe von GIFs</string>
<string name="disable_auto_gif_title">Deaktiviere GIF wiedergabe</string>
<string name="request_changes">angeforderte Änderungen</string>
<string name="google_play_service_error">Google Play-Dienste sind nicht verfügbar</string>
<string name="edit_gist">GIST bearbeiten</string>
<string name="content">Inhalt</string>
<string name="expand">erweitern</string>
<string name="copy_sha">SHA-1 Kopieren</string>
<string name="view_as_code">Als Code anzeigen</string>
<string name="app_animation_title">In-App-Animationen deaktivieren</string>
<string name="app_animation_summary">Deaktiviere in-App-Animationen überall.</string>
<string name="can_not_merge_pr">Dieser PR kann jetzt\jetzt nicht zusammengeführt werden.</string>
<string name="projects">Projekte</string>
<string name="no_projects">Keine Projekte</string>
<string name="no_cards">Keine Karten</string>
<string name="card_added_by">Hinzugefügt von %s %s</string>
<string name="too_large_changes">Zu viele Unterschiede zur Anzeige. Bitte, sehe Sie Sie dir über den Browser an</string>
<string name="project">Projekt</string>
<string name="please_read">BITTE lESEN!</string>
<string name="fasthub_faq_description">
<![CDATA[
<h5>• Warum kann ich meine <b> Organisationen </b> entweder <i> private </i> oder <i> öffentliche </i> sehen\nicht sehen?</h5>
<p>Öffne https://github.com/Settings/Applications und suche nach FastHub, öffne es dann Blätter zu Organisation Zugang und klicke auf den Grant Knopf,
Alternativ melde dich über einen <b> Zugang Token </b> an welches das Setup vereinfacht.</p>
<h5>• Ich habe versuchtt mich mit einem Zugangs Token anzumelden amp; OTP aber es funtioniert nicht?</h5>
<p>Du kannst dich nicht mit einem zugangs token anmelden &amp; OTP alle Zusammen wegen der Lebenszeit des OTP codes, du musst dich alle paar sekunden anmelden</p>
<h5>• Warum werden mein privates Repo &amp; Enterprise Wiki nicht angezeigt?</h5>
<p>Es wie FastHub die GitHub Wiki page holt &amp; Private Repos benötigen einen Sitzungs token denn FastHub nicht bekommen kann.</p>
<h5>• Ich habe mich mit meinen Enterprise account angemeldet kann\kann nicht mit anderen sachen interagieren außer meinem Enterprise GitHub?</h5>
<p>Nun, logisch, kannst du nicht auf etwas anderes als Ihr Unternehmen zugreifen. FastHub versucht, so viel möglich zu erlauben, aber kann
in den meisten Fällen nicht viel dafür tun, da Ihre Anmeldedaten auf den GitHub Server nicht vorhanden sind. Aber in einem <b> paar </b>
fällen Ihr GitHub Konto OAuth Token wird den Trick tun.</p>
<h5>• Warum habe ich Probleme bei der Bearbeitung von Problemen/PRS?</h5>
<p>Wenn du ein öffentliches organisations-repo bearbeiten willst, wende dich bitte an deine organisation, um Zugang zu FastHub zu gewähren oder Zugangsdaten zu verwenden!.</p>
<h5>• Ich habe das problem oder Ich möchte dies &amp; das!!</h5>
<p>Gehe zu https://github.com/k0shk0sh/FastHub/issues/new und erstelle ein neues issue für bugs oder Feature Requests, Ich möchte dich ermutigen
das du vor dem erstellen eines Tickets suchst ob es das schon existiert.Jeder doppelter Request wird dazu führen dass du sofort ausgeschlossen wirst.</p>
<h5>• Wie bekomme ich einen PROMO CODE?</h5>
<p>Wenn du ein Student bist musst du mir eine e-Mail schicken,in der du mir beweist das du ein Student bist, Du brauchst die unten stehen den dokumente:</p>
<ul>
<li>Deine Universitätenausweis & deinen Personalausweis (der deinen Namen zeigt & und dein Gesicht um es zu vergleichen!)</li>
<li>Dein Uni-Start & Enddatum</li>
<li>Bewerte FastHub im Play Store</li>
</ul>
<p>Wenn du kein Student bist und du kannst es dir nicht leisten für PRO zu bezahlen, musst du:</p>
<ul>
<li>Einen Arctikel über Fasthub schreiben in Social Media wie (Medium)</li>
<li>Bewerte FastHub im Play Store</li>
</ul>
]]></string>
<string name="faq">FAQ</string>
<string name="comments_added_successfully">Kommentare erfolgreich hinzugefügt</string>
</resources>

View File

@ -39,7 +39,7 @@
<string name="contributors">Colaboradores</string>
<string name="contributions">Colaboraciones</string>
<string name="by">por</string>
<string name="close_issue">Clonar Issue</string>
<string name="close_issue">Cerrar Issue</string>
<string name="re_open_issue">Reabrir Issue</string>
<string name="re_open">Reabrir</string>
<string name="close">Cerrar</string>
@ -217,10 +217,10 @@
<string name="author">Autor</string>
<string name="fork_github">Fork en GitHub</string>
<string name="send_email">Enviar un email</string>
<string name="question_concerning_fasthub">¿Tenés preguntas sobre FastHub?</string>
<string name="question_concerning_fasthub">¿Tienes preguntas sobre FastHub?</string>
<string name="feedback">Comentarios</string>
<string name="report_issue">Reportar un error</string>
<string name="report_issue_here">¿Tenés un problema? Reportalo aquí</string>
<string name="report_issue_here">¿Tienes un problema? Repórtalo aquí</string>
<string name="about">Acerca de</string>
<string name="notification_settings">Notificación</string>
<string name="turn_off">Apagar</string>

View File

@ -139,7 +139,7 @@
<string name="star_hint">저장소 즐겨찾기/즐겨찾기해제</string>
<string name="watch">구독</string>
<string name="watch_hint">저장소 구독/구독해제</string>
<string name="pin_repo_hint">사이드바에서 더 빨리 액세스 할 수 있도록 저장소를 고정하세요</string>
<string name="pin_repo_hint">사이드바에서 더 빨리 액세스 할 수 있도록 저장소를 바로가기에 등록하세요</string>
<string name="dismiss_all">모두 닫기</string>
<string name="no_url">URL을 찾을 수 없습니다</string>
<string name="last_updated">마지막 업데이트</string>
@ -153,7 +153,7 @@
<string name="mark_all_as_read">모두 읽음으로 표시</string>
<string name="all_notifications">모든 알림</string>
<string name="unread">읽지 않음</string>
<string name="all">모든</string>
<string name="all">전체</string>
<string name="delete_repo">저장소 삭제</string>
<string name="delete_repo_warning">저장소 삭제는 되돌릴 수 없습니다</string>
<string name="thirty_minutes">30분</string>
@ -247,13 +247,13 @@
<string name="support_development">개발 지원</string>
<string name="success_purchase_message">대단히 감사합니다!</string>
<string name="change_theme_warning">테마가 제대로 적용되지 않으면, 앱을 수동으로 재시작해주세요</string>
<string name="pin">고정</string>
<string name="pinned">고정됨</string>
<string name="unpin">고정해</string>
<string name="empty_pinned_repos">아직 고정된 저장소가 없으므로 여기에서 볼 수 있도록 고정하세요.\nP.S: 많이 액세스할수록 저장소는 위에 배치될 것입니다.</string>
<string name="pin">북마크</string>
<string name="pinned">바로가기</string>
<string name="unpin">바로가기 삭</string>
<string name="empty_pinned_repos">아직 바로가기 저장소가 없으므로 여기에서 볼 수 있도록 등록하세요.\nP.S: 많이 액세스할수록 저장소는 위에 배치될 것입니다.</string>
<string name="yes"></string>
<string name="no">아니요</string>
<string name="no_feeds">Feeds 없음</string>
<string name="no_feeds">소식 없음</string>
<string name="no_gists">Gists 없음</string>
<string name="no_comments">덧글 없음</string>
<string name="no_notifications">알림 없음</string>
@ -279,12 +279,12 @@
<string name="changelog">변경사항</string>
<string name="notifications_hint">클릭하여 알림 목록을 열거나 옆으로 밀어 닫으세요</string>
<string name="home_long_click_hint">길게 누르면 어디서나 기본 화면으로 이동합니다</string>
<string name="created">생성</string>
<string name="assigned">담당</string>
<string name="mentioned">언급</string>
<string name="created">생성</string>
<string name="assigned">담당</string>
<string name="mentioned">언급</string>
<string name="name">이름</string>
<string name="color">색상</string>
<string name="create_label">꼬리표 </string>
<string name="create_label">꼬리표 </string>
<string name="organization">조직</string>
<string name="organizations">조직</string>
<string name="people">구성원</string>
@ -293,7 +293,7 @@
<string name="no_members">구성원 없음</string>
<string name="no_teams">팀 없음</string>
<string name="no_orgs">조직 없음</string>
<string name="no_orgs_dialog_title">너의 조직을 찾을 수 없습니까?</string>
<string name="no_orgs_dialog_title">조직을 찾을 수 없습니까?</string>
<string name="mark_as_read">읽음으로 표시</string>
<string name="animations">효과</string>
<string name="dialog_animation_summary">팝업 효과를 활성화합니다</string>
@ -321,7 +321,7 @@
<string name="no_reactions">반응 없음</string>
<string name="reactions">반응</string>
<string name="wrap_content">줄 바꿈</string>
<string name="wrap_code_summary">기본적으로 코드 뷰어에서 코드 줄 바꿈</string>
<string name="wrap_code_summary">기본적으로 코드 뷰어에서 코드 줄 바꿈을 실행합니다</string>
<string name="wrap_code_title">코드 줄 바꿈</string>
<string name="open_source_libs">오픈소스 라이브러리</string>
<string name="enable_notification_sound_summary">알림음을 활성화합니다</string>
@ -330,15 +330,15 @@
<string name="login_with_personal_token">개인 토큰으로 로그인</string>
<string name="personal_token">개인 토큰</string>
<string name="basic_login">기본 인증으로 로그인</string>
<string name="no_orgs_description">실제로 조직에 속해 있고 여기에서 볼 수 없다면 다음 링크를 따르십시오.
<string name="no_orgs_description">조직에 속해 있고 여기에서 볼 수 없다면 다음 링크를 따르세요.
\nhttps://help.github.com/articles/about-third-party-application-restrictions\nPS: 조직에 FastHub 엑세스 권한을 부여하고 액세스 토큰을 사용해서 로그인할 수 있습니다.\n또한 https://github.com/settings/applications에서 FastHub를 찾아 조직 액세스로 스크롤 한 다음 승인 버튼을 클릭하세요.</string>
<string name="insert">삽입</string>
<string name="select">선택</string>
<string name="select_picture">사진 선택</string>
<string name="support_with_2_00">$2.00 지원</string>
<string name="support_with_5_00">$5.00 지원</string>
<string name="support_with_10_00">$10.00 지원</string>
<string name="support_with_20_00">$20.00 지원</string>
<string name="support_with_2_00">$2.00 기부</string>
<string name="support_with_5_00">$5.00 기부</string>
<string name="support_with_10_00">$10.00 기부</string>
<string name="support_with_20_00">$20.00 기부</string>
<string name="app_language">언어</string>
<string name="language">언어</string>
<string name="choose_language_title">언어 선택</string>
@ -347,7 +347,7 @@
<string name="from">from</string>
<string name="in_value">in</string>
<string name="subscribe">구독</string>
<string name="repo_issues_is_disabled"> 저장소에서 이슈가 사용 중지되었습니다</string>
<string name="repo_issues_is_disabled">슈가 비활성화된 저장소입니다</string>
<string name="access_token">엑세스 토큰</string>
<string name="basic_authentication">기본 인증</string>
<string name="choose_your_login_type">로그인 종류 선택</string>
@ -381,10 +381,10 @@
<string name="edit_banner">배너 선택</string>
<string name="image_error">이미지 불러오기 오류, 다시 시도하세요</string>
<string name="trending">급상승</string>
<string name="not_really_working">GitHub 제한 때문에 emojies로 정렬이 실제로 작동하지 않습니다</string>
<string name="not_really_working">GitHub 제한 때문에 emojies로 정렬이 작동하지 않습니다</string>
<string name="scroll_up">위로 스크롤</string>
<string name="scroll_down">아래로 스크롤</string>
<string name="participated">참여</string>
<string name="participated">참여</string>
<string name="todo_checked">모두 선택됨</string>
<string name="todo_unchecked">모두 선택 취소됨</string>
<string name="divider">구분선</string>
@ -398,9 +398,9 @@
<string name="assignee_added">담당자 추가 성공</string>
<string name="reviewer_added">검토자 추가 성공</string>
<string name="milestone_added">이정표 추가 성공</string>
<string name="feed">Feed</string>
<string name="feed">소식</string>
<string name="premium_theme">프리미엄 테마</string>
<string name="choose_code_theme">코드 색상 표</string>
<string name="choose_code_theme">문법 강조기 테마</string>
<string name="enterprise_login_warning">GitHub API의 모든 항목에 액세스하려면 GitHub 계정에 로그인하십시오.
그렇지 않으면 GitHub API로 전송 된 토큰은 엔터프라이즈 계정에서 전송되기 때문에 Enterprise GitHub가 아닌
다른 항목에 액세스 할 때마다 강제 로그아웃 될 수 있습니다.</string>
@ -427,4 +427,41 @@
<string name="app_animation_title">앱 애니메이션</string>
<string name="app_animation_summary">모든 앱 애니메이션을 비활성화합니다</string>
<string name="can_not_merge_pr">이 풀 리퀘스트는 현재 병합될 수 없습니다</string>
<string name="projects">프로젝트</string>
<string name="no_projects">프로젝트 없음</string>
<string name="no_cards">카드 없음</string>
<string name="card_added_by">%s %s가 추가함</string>
<string name="too_large_changes">변경사항이 너무 많습니다. 브라우저로 보세요</string>
<string name="project">프로젝트</string>
<string name="please_read">꼭 읽어주세요</string>
<string name="faq">자주하는 질문</string>
<string name="comments_added_successfully">댓글을 성공적으로 추가하였습니다.</string>
<string name="fasthub_faq_description">
<![CDATA[
<h5>• 왜 <i>Private</i> 이나 <i>Public</i>으로 되어진 제 <b>Organizations</b> 을 볼 수 없나요?</h5>
<p>Open up https://github.com/settings/applications 를 열고 Fasthub라는 것을 찾아보세요. 그것을 선택한 후, Organization Access 부분에서 Grant를 눌러주세요. 또는 초기 로그인시 <b>엑세스 토큰</b> 으로 로그인하면 편리합니다.</p>
<h5>• Access Token 과 OTP 으로 로그인을 시도했는데 로그인이 되질 않아요...</h5>
<p>OTP는 일회용 코드입니다. 따리서 유효기간에 인해 엑세스 토큰 + OTP로 로그인이 불가합니다. 이렇게 로그인을 하게 되면 몇 초에 한 번씩 앱이 로그인을 하라고 합니다. 다른 방법을 사용해 주세요.</p>
<h5>• 제 비공개 리포지토리와 엔터프라이즈 위키가 보이질 않아요!</h5>
<p>위 두 정보를 스크랩하려면 특별한 세션 토큰이 필요한데 본 앱을 이 토큰을 받을 수 없습니다. 깃허브 API의 한계이므로 API문의는 깃허브에게 해주세요. 본 앱의 개발자는 API문의를 받지 않습니다.</p>
<h5>• 제가 엔터프라이즈 계정으로 로그인했는데 Enterprise GitHub 외의 다른 것들은 볼 수 없나요?</h5>
<p>결론부터 말하자면 불가능합니다. 본 앱은 여러분이 다른 것들을 볼 수 있게 해 주고 있지만, 기술적 한계로 크게 도움을 드릴 수는 없습니다. 대부분의 경우에는 여러분의 로그인 계정이 깃허브 서버에 상주하고 있기 때문입니다. 그러나 <b>소수/b>의 경우에는 여러분의 OAuth 토큰이 다른 활동을 하게 해 줄 수 있습니다.</p>
<h5>• Issues/PR 를 수정 하는데 문제가 있습니다.</h5>
<p>공개 Organization 리포지토리를 수정하면, 여러분의 Organization에게 문의하여 Fasthub 권환을 받거나 최초 로그인시 엑세스 토큰으로 로그인하세요.</p>
<h5>• 앱을 사용하는데 문제를 발견했어요! / 혹시 이러한 기능을 추가해주실 수 있나요?</h5>
<p>그럼요! https://github.com/k0shk0sh/FastHub/issues/new 로 간 후 새로운 티켓을 만드세요. 티켓을 만들기 전 먼저 전에 있었던 티켓 중 중복되는 것이 없는지 검색해 주세요. 중복시 티켓은 바로 닫힙니다.</p>
<h5>• PROMO CODE는 어떻게 받나요?</h5>
<p>학생인 경우:</p>
<li>자신의 대학(학교) 학생증 & 신분증 복사본 (이름 및 얼굴 대조를 위한 것 입니다. 관련 서류는 인증 후 폐기됩니다.)</li>
<li>자신의 대학(학교)의 시작일 및 졸업일</li>
<li>플레이 스토어에서 FastHub 별점 매기기</li>
</ul>
<ul>
<p>학생이 아니지만 PRO버전을 구매하실 수 없는 경우:</p>
<li>SNS에 Fasthub에 대한 추천 글 및 평가글 올리기.</li>
<li>플레이 스토어에서 FastHub 별점 매기기</li>
</ul>
<h5>위 조건을 만족시킨 후 본 앱의 개발자인 Kosh Sergani에게 이메일을 보내면 검토후 PROMO CODE를 보내 드립니다.</h5>\n
<h5>본 한국어 번역자는 이 앱의 개발에 참여하지 않았습니다. 따라서 기술적 문의는 이 앱의 개발자인 Kosh Sergani에게 해주시기 바랍니다. 본 번역이 앱 사용에 도움이 되셨기를 바랍니다. 감사합니다.</h5>
]]></string>
</resources>

View File

@ -1,7 +1,7 @@
<resources>
<resources>
<string name="in_progress">Carregando, por favor aguarde…</string>
<string name="action">Ação</string>
<string name="settings">Configuraçoes</string>
<string name="settings">Configurações</string>
<string name="discard">Descartar</string>
<string name="cancel">Cancelar</string>
<string name="ok">OK</string>
@ -429,4 +429,14 @@
<string name="view_as_code">Ver como código</string>
<string name="app_animation_title">Animações no App</string>
<string name="app_animation_summary">Desabilitar todas as animações no App.</string>
<string name="english_please">Por favor envie seu pedido em inglês.</string>
<string name="open_new_window">Abrir em nova janela</string>
<string name="projects">Projetos</string>
<string name="project">Projeto</string>
<string name="card_added_by">Adicionado por %s %s</string>
<string name="no_projects">Sem Projetos</string>
<string name="no_cards">Sem Cartões</string>
<string name="too_large_changes">Muitas diferenças para exibir. Por favor, veja-os via navegador</string>
<string name="no_orgs_dialog_title">Não encontra suas Organizações\?</string>
<string name="can_not_merge_pr">Este PR não pode ser merged agora.</string>
</resources>

View File

@ -434,5 +434,7 @@
<string name="projects">Проекты</string>
<string name="no_projects">Проекты отсутствуют</string>
<string name="no_cards">Карточки отсутствуют</string>
<string name="card_added_by">Добавлено %s</string>
<string name="card_added_by">Добавлено %s %s</string>
<string name="too_large_changes">Слишком много изменений для отображения. Посмотрите их, пожалуйста, в браузере</string>
<string name="project">Проект</string>
</resources>

View File

@ -1,13 +1,33 @@
<!-- Git glossary: https://github.com/git/git/blob/master/po/zh_CN.po -->
<!--
Simplified-Chinese Translation Style Guide
简体中文翻译风格规范 v1.0
继承自作者钦定的翻译贡献指南, 如有冲突请以作者的规定为准:
https://github.com/k0shk0sh/FastHub/blob/master/.github/CONTRIBUTING.md#contribute-translations
0. 专有名词 (如 Issue, Pull Request, Fork, Access Token 等) 不进行翻译,
尽可能避免熟悉英文原词的用户见到翻译后 "咦这是什么东西来着的" 情况的发生.
1. 使用半角标点符号
2. 在西文字符与中文字符前后加入空格 (除标点符号外, 见下一条)
3. 标点符号后空一格
4. 错误提示信息除特殊情况外统一为 "xxxx时发生错误"
5. 统一将 account 译为 "帐号" 而非 "账号" "帐户" 等.
6. "登录"不是"登陆"; "请稍候"不是"请稍后"; "请稍后再试" 不是 "请稍候再试".
7. 如果觉得此规范有什么问题, 欢迎改进或重写 0w0 只要所有文本的风格大体遵守同一个规范就好.
这套规范的主要目的是保持风格统一, 避免出现一个 APP 多种文本的混乱情况.
-->
<!-- 原文版本 (Original strings): 2017/09/24 -->
<resources>
<string name="in_progress">加载中, 请稍候…</string>
<string name="in_progress">加载中, 请稍候...</string>
<string name="action">动作</string>
<string name="settings">设置</string>
<string name="discard">丢弃</string>
<string name="cancel">取消</string>
<string name="ok">确定</string>
<string name="no_data">无可用数据</string>
<string name="search">搜索</string>
<string name="please_login">请登录以继续使用FastHub</string>
<string name="please_login">请登录以使用 FastHub</string>
<string name="sign_in_to_github">登录你的 GitHub 账户来使用 FastHub</string>
<string name="failed_login">无法登录</string>
<string name="sign_in">登录</string>
@ -26,30 +46,40 @@
<string name="unfollow">取消关注</string>
<string name="user">用户</string>
<string name="details">详细信息</string>
<string name="archive_file_detected_error">检测到存档文件,请下载文件查看其内容。</string>
<string name="minimum_three_chars">最少字数3</string>
<string name="archive_file_detected_error">检测到存档文件, 请下载以查看内容.</string>
<string name="minimum_three_chars">最少字数 (3)</string>
<string name="no_file_found">未找到文件</string>
<string name="no_readme_found">没有简介</string>
<string name="downloading">下载中</string>
<string name="downloading_file">下载文件中</string>
<string name="no_readme_found">没有 Readme</string>
<string name="downloading">下载中...</string>
<string name="downloading_file">下载文件中...</string>
<string name="released">发布于</string>
<string name="drafted">草稿</string>
<string name="releases">发布</string>
<string name="no_body">没有内容</string>
<string name="contributors">贡献者</string>
<string name="contributions">贡献</string>
<string name="by"></string>
<string name="close_issue">关闭缺陷跟踪</string>
<string name="re_open_issue">重新打开缺陷跟踪</string>
<string name="english_please">请使用英语描述您的问题.</string>
<string name="close_issue">关闭 Issue</string>
<string name="re_open_issue">重新打开 Issue</string>
<string name="re_open">重新打开</string>
<string name="close">关闭</string>
<string name="success_re_opened">已重新打开</string>
<string name="lock_issue_details">锁定意味着:\n&#183;其他用户无法为此缺陷跟踪添加新评论。\n&#183;您和其他有权访问此仓库的协作者仍然可以留下所有人能看到的评论。\n&#183;您可以随时解锁此缺陷跟踪 。</string>
<string name="unlock_issue_details">解锁意味着:\n&#183;每个人都可以再次对这个缺陷跟踪发表评论。\n&#183;您可以随时再次锁定此缺陷跟踪。\n</string>
<string name="lock_issue_details">锁定意味着:\n
·其他用户无法为此 Issue 添加新评论;\n
·您和其他有写入权限的协作者仍然可以留下所有人都能看到的评论;\n
·您可以随时解锁此 Issue;\n
</string>
<string name="unlock_issue_details">解锁意味着:\n
·每个人都可以对这个 Issue 发表评论;\n
·您可以随时再次锁定此 Issue.\n
</string>
<string name="lock_issue">锁定</string>
<string name="unlock_issue">解锁</string>
<string name="error_closing_issue">关闭缺陷跟踪出错,请稍后再试。</string>
<string name="error_re_opening_issue">重新打开缺陷跟踪出错, 请稍后再试。</string>
<string name="success_closed">已关闭缺陷跟踪 </string>
<string name="no_description_provided"><p>没有提供描述</p></string>
<string name="error_closing_issue">关闭 Issue 时发生错误, 请稍后再试.</string>
<string name="error_re_opening_issue">重新打开 Issue 时发生错误, 请稍后再试.</string>
<string name="success_closed">Issue 已关闭</string>
<string name="no_description_provided">无描述</string>
<string name="header_one">一级标题</string>
<string name="header_two">二级标题</string>
<string name="header_three">三级标题</string>
@ -66,131 +96,146 @@
<string name="addition">添加</string>
<string name="changes">变化</string>
<string name="status">状态</string>
<string name="confirm_message">确定吗?</string>
<string name="confirm_message">确定?</string>
<string name="success">成功</string>
<string name="to"></string>
<string name="error_deleting_comment">删除评论出错</string>
<string name="error_deleting_comment">删除评论时发生错误</string>
<string name="delete">删除</string>
<string name="comments">评论</string>
<string name="comment">评论</string>
<string name="success_merge">已合并</string>
<string name="file">文件</string>
<string name="file_menu">文件菜单</string>
<string name="files">文件</string>
<string name="download">下载</string>
<string name="back">返回</string>
<string name="parent_folder">上级文件夹</string>
<string name="code_viewer">代码查看器</string>
<string name="open_in_browser">用浏览器打开</string>
<string name="open_in_browser">在浏览器中打开</string>
<string name="big_file">大文件</string>
<string name="big_file_description">该文件太大,无法打开。\n触摸“确定”下载。</string>
<string name="big_file_description">该文件太大, 无法在线预览.\n点按"确定"下载.</string>
<string name="viewer">观众</string>
<string name="submit">提交</string>
<string name="type_here">在此输入内容</string>
<string name="description">描述</string>
<string name="file_name">文件名</string>
<string name="file_name_hint">带扩展名的文件名</string>
<string name="create_secret_gist">私有代码片段</string>
<string name="create_public_gist">共代码片段</string>
<string name="create_secret_gist">私有 Gist</string>
<string name="create_public_gist">开 Gist</string>
<string name="submit_as">提交为</string>
<string name="delete_gist">删除</string>
<string name="error_deleting_gist">删除代码片段出错</string>
<string name="error_deleting_gist">删除 Gist 时发生错误</string>
<string name="no_files">没有文件</string>
<string name="required_field">必填项目</string>
<string name="required_field">必填</string>
<string name="successfully_submitted">已提交</string>
<string name="create_gist">创建代码片段</string>
<string name="create_gist">创建 Gist</string>
<string name="clear">清除</string>
<string name="users">用户</string>
<string name="title">标题</string>
<string name="file">文件</string>
<string name="milestone">里程碑</string>
<string name="assign_myself">分配给自己</string>
<string name="submit_issue">提交缺陷跟踪</string>
<string name="error_creating_issue">创建缺陷跟踪出错</string>
<string name="create_issue">创建缺陷跟踪</string>
<string name="error_highlighting_editor">请取消选择以继续编辑</string>
<string name="submit_issue">提交 Issue</string>
<string name="error_creating_issue">创建 Issue 时发生错误</string>
<string name="create_issue">创建 Issue</string>
<string name="error_highlighting_editor">请取消选择以继续编辑.</string>
<string name="notifications">通知</string>
<string name="unread_notification">你有未读的通知</string>
<string name="open">打开的</string>
<string name="open">打开</string>
<string name="open_new_window">在新窗口中打开</string>
<string name="notification_type">通知类型</string>
<string name="labels">标签</string>
<string name="no_labels">没有标签</string>
<string name="labels_added_successfully">已添加标签</string>
<string name="labels_added_successfully">标签已添加</string>
<string name="submit_feedback">提交反馈</string>
<string name="logout">注销</string>
<string name="thank_you_for_feedback">感谢您的反馈 </string>
<string name="thank_you_for_feedback">感谢您的反馈!</string>
<string name="current_version">当前版本</string>
<string name="version">版本</string>
<string name="support_development_enable_ads">支持开发, 启用广告</string>
<string name="username">用户名</string>
<string name="password">密码</string>
<string name="twoFactor">双因素认证码</string>
<string name="login"></string>
<string name="gist_description">代码片段描述</string>
<string name="avatar_click_hint">触摸头像打开用户的个人资料</string>
<string name="feeds_fork_hint">长按一个分支打开上游或该分支仓库。</string>
<string name="click_here_to_download_release_hint">下载此版本</string>
<string name="twoFactor">两步验证</string>
<string name="login"></string>
<string name="gist_description">Gist 描述</string>
<string name="avatar_click_hint">点按头像打开用户的个人资料</string>
<string name="feeds_fork_hint">长按 Fork 消息以打开上游仓库或此 Fork 的仓库.</string>
<string name="click_here_to_download_release_hint">下载</string>
<string name="options">选项</string>
<string name="click_file_option_hint">下载或分享</string>
<string name="star_hint">收藏/取消收藏 此仓库</string>
<string name="watch">关注</string>
<string name="watch_hint">关注/取消关注 此仓库</string>
<string name="pin_repo_hint">添加书签可以从导航栏快速访问它们。</string>
<string name="no_url">找不到URL</string>
<string name="comment_hint">点按评论以标记其作者或编辑你的评论.\n长按你的评论以删除.</string>
<string name="star_hint">Star/取消 Star 此仓库</string>
<string name="watch">Watch</string>
<string name="watch_hint">Watch/取消 Watch 此仓库</string>
<string name="pin_repo_hint">加入书签以从导航栏快速访问.</string>
<string name="dismiss_all">忽略全部</string>
<string name="no_url">找不到网址</string>
<string name="last_updated">最后更新</string>
<string name="preview">预览</string>
<string name="view_code">预览</string>
<string name="click_to_toggle_highlighting">预览Markdown文本显示效果\n\n左右滑动Markdown编辑器图标以获取更多选项。</string>
<string name="click_to_toggle_highlighting">切换 Markdown 语法高亮. \n滑动 Markdown 编辑器图标可查看更多选项.</string>
<string name="creation_date">创建日期</string>
<string name="creation_date_hint">文件创建时间</string><!-- The default value right ? -->
<string name="last_updated_hint">最后更新时间</string>
<string name="creation_date_hint">文件创建时间</string>
<string name="last_updated_hint">文件的最后更新时间</string>
<string name="mark_all_as_read">全部标记为已读</string>
<string name="all_notifications">所有通知</string>
<string name="unread">未读</string>
<string name="all">全部</string>
<string name="delete_repo">删除仓库</string>
<string name="delete_repo_warning">删除此仓库后不能撤销</string>
<string name="delete_repo_warning">删除操作无法撤销</string>
<string name="thirty_minutes">30 分钟</string>
<string name="twenty_minutes">20 分钟</string>
<string name="ten_minutes">10 分钟</string>
<string name="five_minutes">5 分钟</string>
<string name="one_minute">1 分钟</string>
<string name="one_hour">1 小时</string>
<string name="two_hour">2 小时</string>
<string name="three_hour">3 小时</string>
<string name="created_repo">已创建</string>
<string name="committed">已提交</string>
<string name="downloaded">已下载</string>
<string name="followed">已关注</string>
<string name="commented_on_issue">缺陷跟踪 的评论</string>
<string name="commented_on_issue">评论 Issue</string>
<string name="member">成员</string>
<string name="pr_comment_review">拉取请求 的评论</string>
<string name="pushed">推送给</string>
<string name="team_event">小组</string>
<string name="pr_comment_review">评论 Pull Request</string>
<string name="pushed">Push 到</string>
<string name="team_event">团队</string>
<string name="deleted">已删除</string>
<string name="unknown">未知</string>
<string name="commented_on_commit">提交记录 的评论</string>
<string name="commented_on_commit">评论 Commit</string>
<string name="switch_branch">切换分支</string>
<string name="assignees">受理</string>
<string name="assignees">受理</string>
<string name="edit">修改</string>
<string name="update_issue">更新缺陷跟踪</string>
<string name="update_pull_request">更新拉取请求</string>
<string name="edited">\u2022 已修改</string>
<string name="update_issue">更新 Issue</string>
<string name="update_pull_request">更新 Pull Request</string>
<string name="no_milestones">没有里程碑</string>
<string name="add">添加</string>
<string name="done">完成</string>
<string name="home">主页</string>
<string name="create_milestone">建里程碑</string>
<string name="error_creating_milestone">创建里程碑出错</string>
<string name="create_milestone">里程碑</string>
<string name="error_creating_milestone">建立里程碑时发生错误</string>
<string name="due_on">截止于</string>
<string name="no_assignees">没有受理</string>
<string name="no_assignees">没有受理</string>
<string name="this_value"></string>
<string name="commits_reflected">提交记录已切换到所选分支</string>
<string name="commits_reflected">Commit 已被切换到所选分支</string>
<string name="general_settings">一般</string>
<string name="background_job_summary">更改FastHub检查通知的频率</string>
<string name="background_job_summary">更改 FastHub 检查通知的频率</string>
<string name="background_job_title">通知同步间隔</string>
<string name="every">所有</string>
<string name="behavior">行为</string>
<string name="customization">自定义</string>
<string name="recycler_view_animation_summary">启用列表动画</string>
<string name="recycler_view_animation_title">列表动画</string>
<string name="back_button_summary">禁用确认退出的Toast</string>
<string name="back_button_summary">禁用用于防止意外退出的提示框</string>
<string name="back_button_title">返回键直接退出</string>
<string name="unsaved_data_warning">任何未保存的更改都将被丢弃</string>
<string name="restore">恢复</string>
<string name="backup">备份</string>
<string name="backed_up">备份成功!</string>
<string name="select_backup">选择要还原的备份</string>
<string name="permission_failed">没有权限.</string>
<string name="backup_summary">最后更新: %s</string>
<string name="now">现在</string>
<string name="unsaved_data_warning">丢弃所有未保存的更改?</string>
<string name="private_repo">私人</string>
<string name="rect_avatar_summary">使用圆角矩形头像代替圆形头像</string>
<string name="rect_avatar_title">矩形头像</string>
@ -201,63 +246,65 @@
<string name="question_concerning_fasthub">关于 FastHub 的问题</string>
<string name="feedback">反馈</string>
<string name="report_issue">问题反馈</string>
<string name="report_issue_here">有问题吗? 在这里报告</string>
<string name="report_issue_here">遇到问题? 在此反馈</string>
<string name="about">关于</string>
<string name="notification_settings">通知</string>
<string name="turn_off"></string>
<string name="turn_off"></string>
<string name="unauthorized_user">未登录</string>
<string name="two_factors_otp_error">需要两个认证因素</string>
<string name="no_issue">没有缺陷跟踪</string>
<string name="two_factors_otp_error">需要两步验证</string>
<string name="no_issue">没有 Issue</string>
<string name="copy">复制</string>
<string name="success_copied">已复制</string>
<string name="commit_message">提交说明</string>
<string name="network_error">与服务器通信时发生错误</string>
<string name="unexpected_error">请求API时出现意外错误</string>
<string name="request_error">请求服务器发生错误请稍后再试</string>
<string name="unexpected_error">调用 API 时出现意外错误</string>
<string name="request_error">请求服务器发生错误, 请稍后再试</string>
<string name="marking_as_read">将通知标记为已读</string>
<string name="forking_gist">派生此代码片段</string>
<string name="login_using_your_default_browser">使用默认的浏览器登陆 (OAuth)</string>
<string name="forking_gist">Fork 此 Gist</string>
<string name="login_using_your_default_browser">使用默认浏览器登录 (OAuth)</string>
<string name="or_character"></string>
<string name="mark_notification_title">关闭通知读取状态</string>
<string name="mark_notification_summary">点击通知后,禁止标记为已读。</string>
<string name="mark_notification_title">禁用通知已读状态</string>
<string name="mark_notification_summary">点击通知后不再自动标记为已读.</string>
<string name="theme_title">选择主题</string>
<string name="theme_summary">选择默认使用的主题</string>
<string name="theme_summary">选择默认主题</string>
<string name="theme_color_summary">选择主题强调色</string>
<string name="theme_color_title">主题强调色</string>
<string name="website">网站</string>
<string name="support_development">支持开发</string>
<string name="success_purchase_message">非常感谢</string>
<string name="change_theme_warning">如果主题没有正常显示,请重新打开此应用。</string>
<string name="success_purchase_message">非常感谢!</string>
<string name="change_theme_warning">如果主题没有正常显示, 请手动重启此应用.</string>
<string name="pin">书签</string>
<string name="pinned">书签</string>
<string name="unpin">删除书签</string>
<string name="empty_pinned_repos">空空如也,给仓库添加书签就可以在这里查看了</string>
<string name="yes">确定</string>
<string name="no">没有</string><!-- FACK!!The word is also included in the "No Pull Requests" prompt -->
<string name="empty_pinned_repos">没有书签. \n注: 书签按访问频率降序排列.</string>
<string name="yes"></string>
<string name="no"></string>
<string name="no_feeds">没有动态</string>
<string name="no_gists">没有代码片段</string>
<string name="no_gists">没有 Gist</string>
<string name="no_comments">没有评论</string>
<string name="no_notifications">没有通知</string>
<string name="no_followers">没有被人关注</string>
<string name="no_followers">没有关注</string>
<string name="no_followings">没有关注的人</string>
<string name="no_repos">没有仓库</string>
<string name="no_starred_repos">没有已收藏的仓库</string>
<string name="no_commits">没有提交记录</string>
<string name="no_starred_repos">没有已 Star 的仓库</string>
<string name="no_commits">没有 Commit</string>
<string name="no_contributors">没有贡献者</string>
<string name="no_releases">没有发布版本</string>
<string name="no_closed_issues">没有关闭的缺陷跟踪</string>
<string name="no_opened_issues">没有打开的缺陷跟踪</string>
<string name="no_releases">没有 Releases</string>
<string name="no_closed_issues">没有关闭的 Issue</string>
<string name="no_opened_issues">没有打开的 Issue</string>
<string name="no_events">没有事件</string>
<string name="no_open_pull_requests">没有打开的拉取请求</string>
<string name="no_closed_pull_request">没有关闭的拉取请求</string>
<string name="no_open_pull_requests">没有打开的 Pull Request</string>
<string name="no_closed_pull_request">没有关闭的 Pull Request</string>
<string name="no_search_results">没有搜索结果</string>
<string name="read_write_permission_explanation">请接受权限请求,以便 FastHub 将文件存储在设备上</string>
<string name="public_gists">公共代码片段</string>
<string name="read_write_permission_explanation">请接受权限请求, 允许 FastHub 在设备上储存文件</string>
<string name="public_gists">公共 Gist</string>
<string name="enable_ads">开启广告</string>
<string name="no_issues">没有缺陷跟踪</string>
<string name="no_unread_notifications">没有未读通知</string>
<string name="my_gists">我的代码片段</string>
<string name="no_issues">没有 Issue</string>
<string name="no_unread_notifications">没有未读通知</string>
<string name="my_gists">我的 Gist</string>
<string name="changelog">更新日志</string>
<string name="notifications_hint">击打开通知列表或滑动以关闭</string>
<string name="home_long_click_hint">长按可从任何地方导航到主屏幕</string>
<string name="notifications_hint">按通知列表以查看或滑动以忽略</string>
<string name="home_long_click_hint">长按可从任何地方跳转到主屏幕</string>
<string name="created">已创建</string>
<string name="assigned">被分配</string>
<string name="mentioned">提到我</string>
@ -267,11 +314,12 @@
<string name="organization">组织</string>
<string name="organizations">组织</string>
<string name="people">成员</string>
<string name="teams">小组</string>
<string name="teams">团队</string>
<string name="members">成员</string>
<string name="no_members">没有成员</string>
<string name="no_teams">没有小组</string>
<string name="no_teams">没有团队</string>
<string name="no_orgs">没有加入组织</string>
<string name="no_orgs_dialog_title">找不到你所属的组织?</string>
<string name="mark_as_read">标记为已读</string>
<string name="animations">动画</string>
<string name="dialog_animation_summary">启用弹出动画</string>
@ -283,112 +331,135 @@
<string name="checks_passed">所有检查通过</string>
<string name="sort">排序</string>
<string name="newest">最新的</string>
<string name="oldest"></string>
<string name="oldest"></string>
<string name="most_commented">最多评论</string>
<string name="least_commented">最少评论</string>
<string name="recently_updated">最近更新</string>
<string name="least_recent_updated">最早更新</string>
<string name="least_recent_updated">最久没更新</string>
<string name="up_to_date">已是最新版本!</string>
<string name="new_version">有新版本可用</string>
<string name="empty_search_error">搜索内容不能为空</string>
<string name="long_press_repo_fab_hint">长按创建缺陷跟踪</string>
<string name="commit_can_be_merged">拉取请求可以合并</string>
<string name="reviewed">审核</string>
<string name="long_press_repo_fab_hint">长按创建 Issue</string>
<string name="commit_can_be_merged"> Pull Request 可以被合并</string>
<string name="reviewed">审核</string>
<string name="dismissed_review">驳回</string>
<string name="approved_these_changes">批准</string>
<string name="no_reactions">没有反</string>
<string name="reactions"></string>
<string name="approved_these_changes">认同这些更改</string>
<string name="no_reactions">没有反</string>
<string name="reactions"></string>
<string name="wrap_content">自动换行</string>
<string name="wrap_code_summary">在代码查看器中默认自动换行</string>
<string name="wrap_code_title">自动换行</string>
<string name="open_source_libs">软件许可</string>
<string name="enable_notification_sound_summary">收到通知后,发出声音。</string>
<string name="enable_notification_sound_title">开启通知声音</string>
<string name="login_with_personal_token">用个人令牌登录</string>
<string name="personal_token">个人令牌</string>
<string name="basic_login">使用基本认证登录</string>
<string name="no_orgs_description">如果你实际是某个组织的成员,但你找不到组织,请访问下面的链接。\nhttps://help.github.com/articles/about-oauth-app-access-restrictions\nPS您可以使用访问令牌登录这将授予FastHub权限以查看您的组织列表。</string>
<string name="open_source_libs">开源许可</string>
<string name="enable_notification_sound_summary">收到通知时发出声音.</string>
<string name="enable_notification_sound_title">启用通知声音</string>
<string name="enable_notification_title">启用通知</string>
<string name="login_with_personal_token">用 Personal Token 登录</string>
<string name="personal_token">Personal Token</string>
<string name="basic_login">使用 Basic Auth 登录</string>
<string name="no_orgs_description">
如果你实际是某个组织的成员, 但在此没有显示, 请访问下面的链接:\n
https://help.github.com/articles/about-oauth-app-access-restrictions\n
注: 您可以使用 Access token 登录, 这将授予 FastHub 查看您的组织列表的权限.
</string>
<string name="insert">插入</string>
<string name="select">选择</string>
<string name="select_picture">选择图片</string>
<string name="support_with_2_00">支持 2.00$</string>
<string name="support_with_5_00">支持 5.00$</string>
<string name="support_with_10_00">支持 10.00$</string>
<string name="support_with_20_00">支持 20.00$</string>
<string name="support_with_2_00">捐赠 $2.00</string>
<string name="support_with_5_00">捐赠 $5.00</string>
<string name="support_with_10_00">捐赠 $10.00</string>
<string name="support_with_20_00">捐赠 $20.00$</string>
<string name="app_language">语言</string>
<string name="choose_language_title">选择语言</string>
<string name="choose_language_summary">选择您喜欢的语言</string>
<string name="un_subscribe">取消订阅</string>
<string name="access_token">访问令牌</string>
<string name="add_comment">添加评论</string>
<string name="apply">应用</string>
<string name="assignee_added">已分配</string>
<string name="backed_up">已备份!</string>
<string name="backup">备份</string>
<string name="backup_summary">最后更新:%s</string>
<string name="banners">简介横幅</string>
<string name="basic_authentication">基本认证</string>
<string name="choose_your_login_type">选择登录方式</string>
<string name="contributions">贡献</string>
<string name="customization">自定义</string>
<string name="discard">丢弃</string>
<string name="dismiss_all">跳过全部</string>
<string name="edit_banner">选择横幅</string>
<string name="edited">• 已修改</string>
<string name="enable_notification_title">启用通知</string>
<string name="enable_signature">始终签名</string>
<string name="enable_signature_box">每次选择是否签名</string>
<string name="enable_signature_box_summary">在文本编辑器下每次选择是否签名后发送</string>
<string name="enable_signature_summary">始终签名后发送</string>
<string name="failed_selecting_image">无法加载图像。</string>
<string name="feed">动态</string>
<string name="files_only">文件</string>
<string name="filter">过滤器</string>
<string name="from"></string>
<string name="image_error">加载图片时出错,请重试。</string>
<string name="in_value"></string>
<string name="join_slack">加入 Slack</string>
<string name="join_slack_message">你想加入 FastHub Slack 群组吗?</string>
<string name="language">语言</string>
<string name="milestone_added">已添加里程碑</string>
<string name="new_version">有新版本可用。</string>
<string name="no_reviewers">没有审核者</string>
<string name="no_trending">没有趋势</string>
<string name="no_user_found">找不到用户</string>
<string name="not_really_working">由于 GitHub 的限制,按 Emoji 排序功能异常</string>
<string name="now">现在</string>
<string name="one_hour">1 小时</string>
<string name="participated">已加入</string>
<string name="paths_only">路径</string>
<string name="permission_failed">未授予许可。</string>
<string name="premium_theme">付费主题</string>
<string name="reply">回复</string>
<string name="repo_issues_is_disabled">这个仓库关闭了缺陷跟踪</string>
<string name="reset">重置</string>
<string name="restore">恢复</string>
<string name="review_requests">审核请求</string>
<string name="reviewer_added">审核者已添加</string>
<string name="reviewers">审核者</string>
<string name="scroll_down">向下滚动</string>
<string name="scroll_up">向上滑动</string>
<string name="select_backup">选择要还原的备份</string>
<string name="sent_from_fasthub">使用 %2$s%3$s 从我的 %1$s 发送</string>
<string name="sort_direction">排序方式</string>
<string name="choose_language_title">选择语言</string>
<string name="choose_language_summary">选择您希望 FastHub 使用的语言</string>
<string name="un_subscribe">取消订阅</string>
<string name="from"></string>
<string name="in_value"></string>
<string name="subscribe">订阅</string>
<string name="repo_issues_is_disabled">这个仓库禁用了 Issue</string>
<string name="access_token">Access Token</string>
<string name="basic_authentication">Basic Authentication</string>
<string name="choose_your_login_type">选择登录方式</string>
<string name="files_only">文件</string>
<string name="paths_only">路径</string>
<string name="review_requests">审核请求</string>
<string name="join_slack">加入 Slack</string>
<string name="join_slack_message">你想加入 FastHub Slack 群组吗?</string>
<string name="successfully_invited">已邀请</string>
<string name="tags">标签</string>
<string name="theme_color_summary">选择强调色调</string>
<string name="theme_color_title">主题强调色</string>
<string name="three_hour">3 小时</string>
<string name="todo_checked">已勾选的复选框</string>
<string name="todo_unchecked">未勾选的复选框</string>
<string name="trending">趋势</string>
<string name="two_hour">2 小时</string>
<string name="type">类型</string>
<string name="up_to_date">已经是最新版本!</string>
<string name="reply">回复</string>
<string name="failed_selecting_image">无法加载图像.</string>
<string name="want_to_merge">想要合并</string>
<string name="watchers">关注者</string>
<string name="comment_hint">触摸评论来标记其作者或编辑您的评论。\n\n长按你的评论删除它。</string>
<string name="divider">分割线</string>
<string name="banners_info">使用FastHub 2.5.0,您现在可以更好地为自己的个人资料页面展示横幅。\n\n任何使用FastHub应用的人都会看到您的标题您也可以看到其他人的标题 如果你想为自己创建一个横幅使它成为1280x384或其它等比大小否则可能会被裁剪。\n\n您可以随时添加或更改您的横幅通过创建一个描述为“header.fst”的 Gist其中包含一个有横幅链接的文件。\n\n或者更简单只需使用内置的图像选择器</string>
<string name="drafted">草案</string>
<string name="choose_code_theme">选择代码主题</string>
<string name="reviewers">审核者</string>
<string name="no_reviewers">没有审核者</string>
<string name="sent_from_fasthub">使用 %2$s%3$s 从我的 %1$s 发送</string>
<string name="enable_signature">始终签名</string>
<string name="enable_signature_summary">始终签名后发送</string>
<string name="enable_signature_box">每次选择是否签名</string>
<string name="enable_signature_box_summary">在编辑器下选择每次是否签名</string>
<string name="tags">标签</string>
<string name="add_comment">添加评论</string>
<string name="banners">简介横幅</string>
<string name="banners_info">
从 FastHub 2.5.0 开始, 您可以在个人页面使用横幅来更好的展示自己. \n\n
任何使用 FastHub 应用的人都会看到您的横幅, 您也可以看到其他人的横幅!
如果您想为自己创建一个横幅, 确保其分辨率为 1280x384 或其他等比例大小, 否则显示时可能会被裁剪.\n\n
您可以按照以下步骤随意设置或更改您的横幅: 创建一个描述为 "header.fst", 内容为横幅图片的直链链接的 Gist.\n\n
或还可以更简单, 直接使用内置的图片选择器!
</string>
<string name="edit_banner">选择横幅</string>
<string name="image_error">加载图片时出错, 请重试.</string>
<string name="trending">趋势</string>
<string name="not_really_working">由于 GitHub 的限制, 无法正常按 Emoji 排序</string>
<string name="scroll_up">向上滑动</string>
<string name="scroll_down">向下滑动</string>
<string name="participated">已加入</string>
<string name="no_user_found">找不到用户</string>
<string name="no_trending">没有趋势</string>
<string name="reset">重置</string>
<string name="apply">应用</string>
<string name="filter">过滤器</string>
<string name="type">类型</string>
<string name="sort_direction">排序方式</string>
<string name="assignee_added">已分配</string>
<string name="reviewer_added">审核者已添加</string>
<string name="milestone_added">已添加里程碑</string>
<string name="feed">动态</string>
<string name="premium_theme">付费主题</string>
<string name="choose_code_theme">选择代码高亮主题</string>
<string name="enterprise_login_warning">
请登录你的 Github 帐号以使用 Github API 提供的功能,
否则你将只能使用 Enterprise Github 的功能,
因为 Github API 使用的 Token 是来自于你的 Enterprise 帐号的.
</string>
<string name="add_account">添加帐号</string>
<string name="choose_account">选择帐号</string>
<string name="not_match">不匹配</string>
<string name="warning">警告</string>
<string name="owner">所有者</string>
<string name="original_poster">楼主</string>
<string name="cancel_reviews">取消审核</string>
<string name="colored_navbar_summary">导航栏不再随主题颜色</string>
<string name="colored_navbar_title">导航栏默认样式</string>
<string name="sound_chooser_summary">选择自定义通知提示音</string>
<string name="sound_chooser_title">选择通知提示音</string>
<string name="disable_auto_gif_summary">禁止自动播放 GIF</string>
<string name="disable_auto_gif_title">禁止播放 GIF</string>
<string name="request_changes">需要更改</string>
<string name="google_play_service_error">Google Play 服务不可用</string>
<string name="edit_gist">编辑 Gist</string>
<string name="content">内容</string>
<string name="expand">展开</string>
<string name="copy_sha">复制 SHA-1</string>
<string name="view_as_code">作为代码查看</string>
<string name="app_animation_title">禁用 APP 内动画</string>
<string name="app_animation_summary">关闭所有 APP 内动画.</string>
<string name="can_not_merge_pr">此 Pull Request 目前无法合并.</string>
<string name="projects">项目</string>
<string name="no_projects">无项目</string>
<string name="no_cards">无卡片</string>
<string name="card_added_by">%s 于 %s 新增</string>
<string name="too_large_changes">更改内容过多. 请在浏览器中查看.</string>
<string name="project">项目</string>
<string name="faq">常见问题</string>
</resources>

View File

@ -426,14 +426,14 @@ APP
<string name="sound_chooser_title">選擇通知提示聲</string>
<string name="disable_auto_gif_summary">停用 GIF 自動播放</string>
<string name="disable_auto_gif_title">停用 GIF 自動播放</string>
<string name="english_please">請用英文來提交你的請求</string>
<string name="enterprise_login_warning">請登入到GitHub帳號以使用所有的api功能。否則透過企業帳號向GitHub api發送token將會被拒絕。</string>
<string name="english_please">請用英文來提交你的請求</string>
<string name="enterprise_login_warning">請登入到 GitHub 帳號以使用所有的 api 功能。否則透過企業帳號向 GitHub api 發送 token 將會被拒絕。</string>
<string name="not_match">不匹配</string>
<string name="original_poster">原發布者</string>
<string name="cancel_reviews">取消 Reviews</string>
<string name="request_changes">請求更改</string>
<string name="google_play_service_error">Google Play 服務不可用</string>
<string name="edit_gist">編輯Gist</string>
<string name="edit_gist">編輯 Gist</string>
<string name="content">內容</string>
<string name="expand">展開</string>
<string name="copy_sha">複製 SHA-1</string>
@ -441,9 +441,54 @@ APP
<string name="app_animation_title">停用 App 內部動畫</string>
<string name="app_animation_summary">在每個地方停用 App 內部動畫</string>
<string name="can_not_merge_pr">這個 PR 目前沒辦法被 merge</string>
<string name="projects">" 專案"</string>
<string name="projects">專案</string>
<string name="no_projects">沒有專案</string>
<string name="no_cards">沒有卡</string>
<string name="card_added_by">由 %s 新增</string>
<string name="no_orgs_dialog_title">找不到您的組織嗎?</string>
<string name="open_new_window">在新視窗中開啟</string>
<string name="too_large_changes">差異太多無法顯示。請於瀏覽器檢視它們</string>
<string name="project">專案</string>
<string name="faq">FAQ</string>
<string name="fasthub_faq_description">
<![CDATA[
<h5>• 為何我無法看到我的 <b>組織</b><i>私人</i> / <i>公開</i> 的東西?</h5>
<p>打開 https://github.com/settings/applications 並找到 FastHub 點擊它並滑到 Organization access 並點擊 Grant 按鈕,
或是透過 <b>Access Token</b> 登入將不需要做這件事</p>
<h5>• 我試著透過 Access Token &amp; OTP 登入,但沒作用?</h5>
<p>你不能透過 Access Token &amp; OTP 登入,因為 OTP code 的時限緣故, 你會需要在幾秒鐘內登入。</p>
<h5>• 為何我的私人&amp;企業的 Repo Wiki 無法顯示?</h5>
<p>因為 FastHub 在擷取 GitHub Wiki &amp; 私人 Repos 時需要 session token ,但 FastHub 沒有。</p>
<h5>• 使用企業帳號時無法與任何其他非我的企業的東西互動?</h5>\n
<p>邏輯上來說,你無法存取任何東西非你的企業的東西,不過 FastHub 讓它能成功存取,但沒辦法再做到更多了。
在大部分的情況下你的登入認證不存在於 GitHub 的伺服器上。
但在少數情形之下你的 GitHub 帳號的 Oauth token 能達成這個技巧。</p>
<h5>• 我在編輯 Issues/PRs 遇到困難?</h5>
<p>如果你正在編輯一個公開組職的 Repo ,請聯絡你的組織以取得權限給 FastHub 或是使用 Access Token 來登入!</p>
<h5>• 我被禁止使用 FastHub 了,為什麼?</h5>
<p>很簡單,因為想要某些功能而給了 FastHub 低評價卻從來不更新你的評價。
所以為何你要繼續使用呢?</p>
<h5>• 我有困難/我想要有新功能!!</h5>
<p>前往 https://github.com/k0shk0sh/FastHub/issues/new 並創建一個 bug/feature requests 的 issue。
我非常鼓勵你在發布某些東西前先搜尋有沒有重複的,否則會被馬上關閉。</p>
<i><font color="red">給 FastHub 開發者們的訊息</font></i>\n
<h3>開發者們你好,</h3>\n
<p style="text-align:justify;">
你應該知道 <b>FastHub</b> 是一個成長很快開源的 App &amp; 是因為許多來自社群的幫助以及你們。
\n因為想要回報 issue 或是 request 而在 Play商店 給 <b>FastHub</b> 低評價將會被忽略。
\n作為一個開發者我想我們應該知道開發一個像是 <b>FastHub</b> 要付出多大的努力。
\n有些人不知道要在 FastHub 的 Repo 回報而是在 Play商店 給低評價並且認為這會強制開發者(我) 去實作及修復他們想要的東西,而他們會更新評價。
\n但是這並沒有發生過他們不是不修改評價就是要求其他功能<i>(如此典型)</i>
\n請於 FastHub repo 回報 Issue & Features打開側欄功能表並點擊"回報 Issue",這將會被直接發布在 FastHub repo (我能夠幫助和協助你的地方)。
</p>
]]></string>
<string name="please_read">請閱讀!</string>
</resources>

View File

@ -92,14 +92,14 @@
• All PRO Themes\n
• PR Reviews & On-line code comments (PRs & Commits)\n
• Commit from FastHub (Edit, Create & Delete files)\n
• Support to other Merge methods (Rebase & Squash)\n
• Supports 2 more Merging methods (Rebase & Squash)\n
• Login to unlimited accounts\n
• Edit & Add unlimited Gist Files\n
• Project Columns & Cards (Edit, Create & Delete)
• New upcoming PRO features
• New upcoming PRO features (Coming soon...)
]]></string>
<string name="enterprise_pro_description" translatable="false"><![CDATA[
• Login to unlimited number of Enterprise & GitHub accounts\n
• Login to unlimited number of Enterprise & GitHub accounts\n
• Access GitHub contents along side your Enterprise Account
]]></string>
<string name="purchase" translatable="false">Purchase</string>
@ -124,7 +124,7 @@
<string name="unlock" translatable="false">Unlock</string>
<string name="unlock_everything" translatable="false">Unlock Everything</string>
<string name="feeds" translatable="false">Feeds</string>
<!-- END OF DO NOT COPY START COPYING FROM LINE BELOW -->
<!-- END OF DO NOT COPY, START COPYING FROM LINE BELOW -->
<string name="in_progress">Loading, please wait…</string>
<string name="action">Action</string>
@ -134,9 +134,9 @@
<string name="ok">OK</string>
<string name="no_data">No data available</string>
<string name="search">Search</string>
<string name="please_login">Please sign in to continue using FastHub</string>
<string name="please_login">Please sign in to begin using FastHub</string>
<string name="sign_in_to_github">Sign in using your GitHub account to use FastHub</string>
<string name="failed_login">Failed to sign in</string>
<string name="failed_login"> Sign in failed</string>
<string name="sign_in">Sign in</string>
<string name="share">Share</string>
<string name="reload">Reload</string>
@ -154,7 +154,7 @@
<string name="user">User</string>
<string name="details">Details</string>
<string name="archive_file_detected_error">Archive file detected, please download the file to view its content.</string>
<string name="minimum_three_chars">Minimum characters (3)</string>
<string name="minimum_three_chars">Minimum characters (2)</string>
<string name="no_file_found">No file found</string>
<string name="no_readme_found">No readme found</string>
<string name="downloading">Downloading…</string>
@ -230,7 +230,7 @@
<string name="no_files">No files</string>
<string name="required_field">Required field</string>
<string name="successfully_submitted">Successfully submitted</string>
<string name="create_gist">Create Gist</string>
<string name="create_gist">Create a Gist</string>
<string name="clear">Clear</string>
<string name="users">Users</string>
<string name="title">Title</string>
@ -553,7 +553,7 @@
<string name="disable_auto_gif_summary">Disable auto playing GIFs</string>
<string name="disable_auto_gif_title">Disable Playing GIF</string>
<string name="request_changes">requested changes</string>
<string name="google_play_service_error">Google Play Service unavailable</string>
<string name="google_play_service_error">Google Play Services are unavailable</string>
<string name="edit_gist">Edit Gist</string>
<string name="content">Content</string>
<string name="expand">expand</string>
@ -566,6 +566,46 @@
<string name="no_projects">No Projects</string>
<string name="no_cards">No Cards</string>
<string name="card_added_by">Added by %s %s</string>
<string name="too_large_changes">Changes are large, please open in browser</string>
<string name="too_large_changes">Too many differences to display. Please, view them via browser</string>
<string name="project">Project</string>
<string name="please_read">PLEASE READ!</string>
<string name="fasthub_faq_description">
<![CDATA[
<h5>• Why can\'t I see my <b>Organizations</b> either <i>Private</i> or <i>Public</i> ones?</h5>
<p>Open up https://github.com/settings/applications and look for FastHub, open it then scroll to Organization access and click on Grant Button,
alternatively login via <b>Access Token</b> which will ease this setup.</p>
<h5>• I tried to login via Access Token &amp; OTP but it does not work?</h5>
<p>You can\'t login via Access Token &amp; OTP all together due to the lifetime of the OTP code, you\'ll be required to login in every few seconds.</p>
<h5>• Why are my Private Repo &amp; Enterprise Wiki not showing up?</h5>
<p>It\'s due to FastHub scraping GitHub Wiki page &amp; Private Repos require session token that FastHub is unable to obtain.</p>
<h5>• I login with Enterprise account but can\'t interact with anything other than my Enterprise GitHub?</h5>
<p>Well, logically, you can\'t access anything else other than your Enterprise. FastHub tries to allow as much possible, but can\'t do much about it
in most cases, since your login credential doesn\'t exists in GitHub server. But in a <b>few</b>
cases your GitHub account Oauth token will do the trick.</p>
<h5>• Why am I having problems editing Issues/PRs?</h5>
<p>If you are editing a public Org repo, then please contact your Org to grant access to FastHub or use Access Token to login!.</p>
<h5>• I\'m having this issue or I want this &amp; that!!</h5>
<p>Head to https://github.com/k0shk0sh/FastHub/issues/new and create new issue for bugs or feature requests, I really do encourage you to
search before opening a ticket. Any duplicate request will result in it being closed immediately.</p>
<h5>• How do I get PROMO CODE?</h5>
<p>If you are a student, you\'ll have to provide me via Email that you are student, you will need below documents:</p>
<ul>
<li>Your university identity card & your identity card (that shows your name & your face to compare it!)</li>
<li>Your university start & end date</li>
<li>Rate FastHub in the Play Store</li>
</ul>
<p>If you aren\'t a student and you can\'t afford to pay for PRO, you\'ll need:</p>
<ul>
<li>Write an article about FastHub in social media such as (Medium)</li>
<li>Rate FastHub in the Play Store</li>
</ul>
]]></string>
<string name="faq">FAQ</string>
<string name="comments_added_successfully">Comments added successfully</string>
</resources>

View File

@ -5,7 +5,7 @@ buildscript {
state_version = '1.1.0'
lombokVersion = '1.12.6'
supportVersion = "26.0.1"
gms = "11.2.0"
gms = "11.4.0"
thirtyinchVersion = '0.8.0'
retrofit = '2.3.0'
junitVersion = '4.12'
@ -13,7 +13,7 @@ buildscript {
assertjVersion = '2.5.0'
espresseVersion = '2.2.2'
requery = '1.3.2'
kotlin_version = '1.1.4-2'
kotlin_version = '1.1.51'
commonmark = '0.9.0'
}
repositories {
@ -22,7 +22,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-beta5'
classpath 'com.android.tools.build:gradle:3.0.0-beta7'
classpath 'com.google.gms:google-services:3.0.0'
classpath 'com.novoda:gradle-build-properties-plugin:0.3'
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.2'

View File

@ -3,5 +3,5 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.2-all.zip
android.enableD8=true

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