mirror of
https://codeberg.org/gitnex/GitNex.git
synced 2023-12-13 20:50:18 +01:00
Cherry-pick enhancements and features from #897. I didn't pick database-related stuff because I don't think it's a good idea to do this (see discord conversation). Closes #598 Closes #887 Closes #888 Closes #901 Closes #1024 Closes #1035 Co-authored-by: opyale <opyale@noreply.codeberg.org> Co-authored-by: qwerty287 <ndev@web.de> Co-authored-by: M M Arif <mmarif@noreply.codeberg.org> Co-authored-by: M M Arif <mmarif@swatian.com> Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1032 Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org> Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
This commit is contained in:
parent
24c7176753
commit
56ff09d44d
84 changed files with 2104 additions and 1933 deletions
|
@ -31,7 +31,7 @@ labels:
|
|||
<!-- Screenshots and stacktrace's can go here. -->
|
||||
<br><br>
|
||||
|
||||
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
|
||||
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/gitnex/GitNex/wiki/Contributing).
|
||||
<br>
|
||||
|
||||
<!-- Thank you for your time. -->
|
||||
<!-- Thank you for your time. -->
|
||||
|
|
|
@ -11,7 +11,7 @@ labels:
|
|||
## # Describe your matter briefly
|
||||
<br><br>
|
||||
|
||||
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
|
||||
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/gitnex/GitNex/wiki/Contributing).
|
||||
<br>
|
||||
|
||||
<!-- Thank you for your time. -->
|
||||
|
|
|
@ -31,7 +31,7 @@ labels:
|
|||
<!-- Screenshots and stacktrace's can go here. -->
|
||||
<br><br>
|
||||
|
||||
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/GitNex/GitNex/src/branch/main/CONTRIBUTING.md).
|
||||
- [ ] I carefully read the [contribution guidelines](https://codeberg.org/gitnex/GitNex/wiki/Contributing).
|
||||
<br>
|
||||
|
||||
<!-- Thank you for your time. -->
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
# Contributing to GitNex
|
||||
|
||||
Please take a few minutes to read this document to make the process of contribution more easy and healthy for all involved.
|
||||
|
||||
### General
|
||||
> **Be polite and gentle while commenting or creating new issues to maintain a healthy environment in which __everyone__ is able to feel comfortable.**
|
||||
<br>
|
||||
|
||||
### Issues and Reports
|
||||
Before creating an issue please take a moment and search the repository issues(open/closed) to avoid duplicate issues either it's a bug or feature.
|
||||
In case you want to submit a bug report, please provide as much details as possible to better debug the problem. The important part is how to reproduce the bug and steps to reproduce are appreciated.<br><br>
|
||||
**Note:** Please contact the project directly via [email](mailto:gitnex@swatian.com) if have to share sensitive and security related details.
|
||||
<br>
|
||||
|
||||
### Pull Requests
|
||||
Patches, enhancements and features are always welcome.
|
||||
The PR should focus on the scope of work and avoid many unnecessary commits.
|
||||
Please provide as much detail and context as possible to explain the work submitted.
|
||||
|
||||
**Please ask if you are not sure about the scope of work to be submitted to avoid waste of time spent on the work.** (Submit an issue, __before__ submitting a PR)
|
||||
|
||||
**Code Standards**<br><br>
|
||||
Please follow the code standards, this will help other developers to understand your code too.
|
||||
It also helps maintaining the code afterwards.
|
||||
It is documented in the Wiki: [Code-Standards](https://codeberg.org/gitnex/GitNex/wiki/Code-Standards)
|
||||
|
||||
**How to submit a PR (Pull Request)**
|
||||
1. Fork this repository.
|
||||
2. Clone the forked repository from your namespace to your local machine.
|
||||
3. Create a new branch and work on your feature, enhancement or patch.
|
||||
4. Push your commits to your forked version.
|
||||
5. You can now create a PR using the web interface against **main** branch.
|
||||
|
||||
For more information, click [here](http://makeapullrequest.com/).
|
||||
|
||||
**IMPORTANT:** By submitting PR, you agree to allow GitNex to license your work under the same license as that used by GitNex.
|
|
@ -1,37 +0,0 @@
|
|||
# Contributors
|
||||
This part lists all PUBLIC individuals having contributed content to the code.
|
||||
|
||||
* M M Arif (mmarif)
|
||||
* 6543
|
||||
* opyale
|
||||
* Unpublished
|
||||
|
||||
# Translators
|
||||
This part lists all PUBLIC individuals having contributed content to the translation.
|
||||
*Entries are in alphabetical order*
|
||||
|
||||
* 6543
|
||||
* acrylicpaintboy
|
||||
* Antoine GIRARD (sapk)
|
||||
* BaRaN6161_TURK
|
||||
* ButterflyOfFire (BoFFire)
|
||||
* dadosch
|
||||
* erardiflorian
|
||||
* IndeedNotJames
|
||||
* jaqra
|
||||
* Lafriks
|
||||
* ljoonal
|
||||
* Lunny Xiao (xiaolunwen)
|
||||
* lxs
|
||||
* Marcos de Oliveira (markkrj)
|
||||
* mmarif
|
||||
* Nadezhda Moiseeva (digitalkiller)
|
||||
* Oleg Popenkov (FanHamMer)
|
||||
* PsychotherapistSam
|
||||
* Rodion Borisov (vintproykt)
|
||||
* s4ne
|
||||
* valeriezhao1013
|
||||
* Vladislav Glinsky (cl0ne)
|
||||
* Voyvode
|
||||
|
||||
**Thank you for all your work** :+1:
|
|
@ -37,7 +37,7 @@ Option 2 - Open terminal(Linux) and cd to the project dir. Run `./gradlew assemb
|
|||
- [MANY MORE](https://codeberg.org/gitnex/GitNex/wiki/Features)
|
||||
|
||||
## Contributing
|
||||
[CONTRIBUTING](https://codeberg.org/gitnex/GitNex/src/branch/main/CONTRIBUTING.md)
|
||||
[Contributing](https://codeberg.org/gitnex/GitNex/wiki/Contributing)
|
||||
|
||||
## Translation
|
||||
Help us translate GitNex to your native language.
|
||||
|
|
|
@ -6,7 +6,7 @@ android {
|
|||
applicationId "org.mian.gitnex"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 31
|
||||
versionCode 415
|
||||
versionCode 420
|
||||
versionName "4.2.0"
|
||||
multiDexEnabled true
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
@ -54,9 +54,9 @@ configurations {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
def lifecycle_version = '2.4.0'
|
||||
def lifecycle_version = '2.4.1'
|
||||
def markwon_version = '4.6.2'
|
||||
def work_version = "2.7.0-alpha05"
|
||||
def work_version = "2.7.1"
|
||||
def acra = "5.7.0"
|
||||
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
|
@ -114,5 +114,4 @@ dependencies {
|
|||
implementation 'androidx.biometric:biometric:1.1.0'
|
||||
implementation 'com.github.chrisvest:stormpot:2.4.2'
|
||||
implementation 'androidx.browser:browser:1.4.0'
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
android:roundIcon="@mipmap/app_logo_round"
|
||||
android:supportsRtl="true"
|
||||
tools:targetApi="n">
|
||||
|
||||
<activity
|
||||
android:name=".activities.MergePullRequestActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
|
@ -60,7 +59,7 @@
|
|||
android:name=".activities.CreateTeamByOrgActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.OrganizationTeamMembersActivity"
|
||||
android:name=".activities.OrganizationTeamInfoActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.OrganizationDetailActivity"
|
||||
|
@ -85,12 +84,11 @@
|
|||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
<activity
|
||||
android:name=".activities.MainActivity"
|
||||
android:theme="@android:style/Theme.NoTitleBar"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:theme="@android:style/Theme.NoTitleBar"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
@ -98,7 +96,7 @@
|
|||
android:name=".activities.LoginActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@android:style/Theme.NoTitleBar"/>
|
||||
android:theme="@android:style/Theme.NoTitleBar" />
|
||||
<activity
|
||||
android:name=".activities.CreateRepoActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
|
@ -108,6 +106,10 @@
|
|||
<activity
|
||||
android:name=".activities.FileDiffActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
<activity
|
||||
android:name=".activities.DiffActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:theme="@android:style/Theme.NoTitleBar" />
|
||||
<activity
|
||||
android:name=".activities.CommitsActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
|
@ -154,28 +156,28 @@
|
|||
<activity
|
||||
android:name=".activities.SettingsNotificationsActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.AdminCronTasksActivity"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||
|
||||
<!-- Version < 3.0. DeX Mode and Screen Mirroring support -->
|
||||
<meta-data android:name="com.samsung.android.keepalive.density" android:value="true"/>
|
||||
<!-- Version >= 3.0. DeX Dual Mode support -->
|
||||
<meta-data android:name="com.samsung.android.multidisplay.keep_process_alive" android:value="true"/>
|
||||
|
||||
<!-- deep links -->
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" /> <!-- Version < 3.0. DeX Mode and Screen Mirroring support -->
|
||||
<meta-data
|
||||
android:name="com.samsung.android.keepalive.density"
|
||||
android:value="true" /> <!-- Version >= 3.0. DeX Dual Mode support -->
|
||||
<meta-data
|
||||
android:name="com.samsung.android.multidisplay.keep_process_alive"
|
||||
android:value="true" /> <!-- deep links -->
|
||||
<activity
|
||||
android:name=".activities.DeepLinksActivity"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"
|
||||
android:noHistory="true"
|
||||
android:launchMode="singleTask"
|
||||
android:noHistory="true"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:host="codeberg.org" />
|
||||
|
@ -185,17 +187,7 @@
|
|||
<data android:host="git.fsfe.org" />
|
||||
<data android:host="opendev.org" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="gitnex" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<!-- deep links -->
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
package org.mian.gitnex.actions;
|
||||
|
||||
import android.content.Context;
|
||||
import org.gitnex.tea4j.models.NotificationThread;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import retrofit2.Call;
|
||||
|
||||
/**
|
||||
* Author opyale
|
||||
*/
|
||||
|
||||
public class NotificationsActions {
|
||||
|
||||
public enum NotificationStatus {READ, UNREAD, PINNED}
|
||||
|
||||
private TinyDB tinyDB;
|
||||
private Context context;
|
||||
private String instanceToken;
|
||||
|
||||
public NotificationsActions(Context context) {
|
||||
|
||||
this.context = context;
|
||||
this.tinyDB = TinyDB.getInstance(context);
|
||||
|
||||
String loginUid = tinyDB.getString("loginUid");
|
||||
|
||||
instanceToken = "token " + tinyDB.getString(loginUid + "-token");
|
||||
|
||||
}
|
||||
|
||||
public void setNotificationStatus(NotificationThread notificationThread, NotificationStatus notificationStatus) throws IOException {
|
||||
|
||||
Call<Void> call = RetrofitClient.getApiInterface(context)
|
||||
.markNotificationThreadAsRead(instanceToken, notificationThread.getId(), notificationStatus.name());
|
||||
|
||||
if(!call.execute().isSuccessful()) {
|
||||
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setAllNotificationsRead(Date date) throws IOException {
|
||||
|
||||
Call<Void> call = RetrofitClient.getApiInterface(context)
|
||||
.markNotificationThreadsAsRead(instanceToken, AppUtil.getTimestampFromDate(context, date), true,
|
||||
new String[]{"unread", "pinned"}, "read");
|
||||
|
||||
return call.execute().isSuccessful();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -124,7 +124,7 @@ public class CreateFileActivity extends BaseActivity {
|
|||
disableProcessButton();
|
||||
|
||||
NetworkStatusObserver networkStatusObserver = NetworkStatusObserver.getInstance(ctx);
|
||||
networkStatusObserver.registerNetworkStatusListener(binding.newFileCreate::setEnabled);
|
||||
networkStatusObserver.registerNetworkStatusListener(hasNetworkConnection -> runOnUiThread(() -> binding.newFileCreate.setEnabled(hasNetworkConnection)));
|
||||
|
||||
binding.newFileCreate.setOnClickListener(v -> processNewFile());
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.ActivityDiffBinding;
|
||||
import org.mian.gitnex.fragments.DiffFilesFragment;
|
||||
import org.mian.gitnex.fragments.DiffFragment;
|
||||
|
||||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
|
||||
public class DiffActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityDiffBinding binding = ActivityDiffBinding.inflate(getLayoutInflater());
|
||||
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
DiffFilesFragment fragment = DiffFilesFragment.newInstance();
|
||||
|
||||
getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) {
|
||||
|
||||
@Override
|
||||
public void handleOnBackPressed() {
|
||||
if(getSupportFragmentManager().findFragmentById(R.id.fragment_container) instanceof DiffFragment) {
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, fragment)
|
||||
.commit();
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, fragment)
|
||||
.commit();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import org.gitnex.tea4j.models.FileDiffView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.FilesDiffAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.ActivityFileDiffBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.ParseDiff;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class FileDiffActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private TextView toolbarTitle;
|
||||
private ListView mListView;
|
||||
private ProgressBar mProgressBar;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityFileDiffBinding activityFileDiffBinding = ActivityFileDiffBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityFileDiffBinding.getRoot());
|
||||
|
||||
Toolbar toolbar = activityFileDiffBinding.toolbar;
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
final TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
String repoFullName = tinyDb.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
ImageView closeActivity = activityFileDiffBinding.close;
|
||||
toolbarTitle = activityFileDiffBinding.toolbarTitle;
|
||||
mListView = activityFileDiffBinding.listView;
|
||||
mProgressBar = activityFileDiffBinding.progressBar;
|
||||
|
||||
mListView.setDivider(null);
|
||||
|
||||
toolbarTitle.setText(R.string.processingText);
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
String pullIndex = tinyDb.getString("issueNumber");
|
||||
|
||||
boolean apiCall = !new Version(tinyDb.getString("giteaVersion")).less("1.13.0");
|
||||
getPullDiffContent(repoOwner, repoName, pullIndex, apiCall);
|
||||
|
||||
}
|
||||
|
||||
private void getPullDiffContent(String owner, String repo, String pullIndex, boolean apiCall) {
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
Call<ResponseBody> call = apiCall ?
|
||||
RetrofitClient.getApiInterface(ctx).getPullDiffContent(Authorization.get(ctx), owner, repo, pullIndex) :
|
||||
RetrofitClient.getWebInterface(ctx).getPullDiffContent(Authorization.getWeb(ctx), owner, repo, pullIndex);
|
||||
|
||||
try {
|
||||
|
||||
Response<ResponseBody> response = call.execute();
|
||||
assert response.body() != null;
|
||||
|
||||
switch(response.code()) {
|
||||
|
||||
case 200:
|
||||
List<FileDiffView> fileDiffViews = ParseDiff.getFileDiffViewArray(response.body().string());
|
||||
|
||||
int filesCount = fileDiffViews.size();
|
||||
|
||||
String toolbarTitleText = (filesCount > 1) ?
|
||||
getResources().getString(R.string.fileDiffViewHeader, Integer.toString(filesCount)) :
|
||||
getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount));
|
||||
|
||||
FilesDiffAdapter adapter = new FilesDiffAdapter(ctx, getSupportFragmentManager(), fileDiffViews);
|
||||
|
||||
runOnUiThread(() -> {
|
||||
toolbarTitle.setText(toolbarTitleText);
|
||||
mListView.setAdapter(adapter);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
});
|
||||
break;
|
||||
|
||||
case 401:
|
||||
runOnUiThread(() -> AlertDialogs.authorizationTokenRevokedDialog(ctx,
|
||||
getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getString(R.string.cancelButton),
|
||||
getString(R.string.navLogout)));
|
||||
break;
|
||||
|
||||
case 403:
|
||||
runOnUiThread(() -> {
|
||||
Toasty.error(ctx, ctx.getString(R.string.authorizeError));
|
||||
finish();
|
||||
});
|
||||
break;
|
||||
|
||||
case 404:
|
||||
runOnUiThread(() -> {
|
||||
Toasty.warning(ctx, ctx.getString(R.string.apiNotFound));
|
||||
finish();
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
runOnUiThread(() -> Toasty.error(ctx, getString(R.string.labelGeneralError)));
|
||||
|
||||
}
|
||||
} catch(IOException ignored) {}
|
||||
|
||||
});
|
||||
|
||||
thread.start();
|
||||
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
|
||||
onClickListener = view -> {
|
||||
|
||||
getIntent().removeExtra("singleFileName");
|
||||
finish();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -202,9 +202,8 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
|
|||
fetchDataAsync(repoOwner, repoName, issueIndex);
|
||||
|
||||
if(getIntent().getStringExtra("openPrDiff") != null && getIntent().getStringExtra("openPrDiff").equals("true")) {
|
||||
startActivity(new Intent(ctx, FileDiffActivity.class));
|
||||
startActivity(new Intent(ctx, DiffActivity.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -224,12 +223,10 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
|
|||
showAssignees();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void labelsInterface(List<String> data) {
|
||||
}
|
||||
public void labelsInterface(List<String> data) { }
|
||||
|
||||
@Override
|
||||
public void labelsIdsInterface(List<Integer> data) {
|
||||
|
|
|
@ -2,7 +2,6 @@ package org.mian.gitnex.activities;
|
|||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
@ -85,60 +84,41 @@ public class LoginActivity extends BaseActivity {
|
|||
selectedProtocol = String.valueOf(parent.getItemAtPosition(position));
|
||||
|
||||
if(selectedProtocol.equals(String.valueOf(Protocol.HTTP))) {
|
||||
|
||||
Toasty.warning(ctx, getResources().getString(R.string.protocolError));
|
||||
}
|
||||
});
|
||||
|
||||
if(R.id.loginToken == loginMethod.getCheckedRadioButtonId()) {
|
||||
|
||||
AppUtil.setMultiVisibility(View.GONE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout));
|
||||
findViewById(R.id.loginTokenCodeLayout).setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
AppUtil.setMultiVisibility(View.VISIBLE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout));
|
||||
findViewById(R.id.loginTokenCodeLayout).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
loginMethod.setOnCheckedChangeListener((group, checkedId) -> {
|
||||
|
||||
if(checkedId == R.id.loginToken) {
|
||||
|
||||
AppUtil.setMultiVisibility(View.GONE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout));
|
||||
findViewById(R.id.loginTokenCodeLayout).setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
AppUtil.setMultiVisibility(View.VISIBLE, findViewById(R.id.login_uidLayout), findViewById(R.id.login_passwdLayout), findViewById(R.id.otpCodeLayout));
|
||||
findViewById(R.id.loginTokenCodeLayout).setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
Handler handler = new Handler(getMainLooper());
|
||||
|
||||
networkStatusObserver.registerNetworkStatusListener(hasNetworkConnection -> {
|
||||
|
||||
handler.post(() -> {
|
||||
|
||||
if(hasNetworkConnection) {
|
||||
|
||||
enableProcessButton();
|
||||
}
|
||||
else {
|
||||
|
||||
disableProcessButton();
|
||||
loginButton.setText(getResources().getString(R.string.btnLogin));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
networkStatusObserver.registerNetworkStatusListener(hasNetworkConnection -> runOnUiThread(() -> {
|
||||
if(hasNetworkConnection) {
|
||||
enableProcessButton();
|
||||
} else {
|
||||
disableProcessButton();
|
||||
loginButton.setText(getResources().getString(R.string.btnLogin));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
}
|
||||
}));
|
||||
|
||||
loadDefaults();
|
||||
|
||||
loginButton.setOnClickListener(view -> {
|
||||
|
||||
disableProcessButton();
|
||||
login();
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.Html;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
|
@ -88,6 +89,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
|||
setContentView(activityMainBinding.getRoot());
|
||||
|
||||
Intent mainIntent = getIntent();
|
||||
Handler handler = new Handler();
|
||||
|
||||
// DO NOT MOVE
|
||||
if(mainIntent.hasExtra("switchAccountId") &&
|
||||
|
@ -97,7 +99,6 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
|||
mainIntent.removeExtra("switchAccountId");
|
||||
recreate();
|
||||
return;
|
||||
|
||||
}
|
||||
// DO NOT MOVE
|
||||
|
||||
|
@ -106,8 +107,6 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
|||
loginUid = tinyDB.getString("loginUid");
|
||||
instanceToken = "token " + tinyDB.getString(loginUid + "-token");
|
||||
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
|
||||
if(!tinyDB.getBoolean("loggedInMode")) {
|
||||
|
||||
logout(this, ctx);
|
||||
|
@ -136,7 +135,6 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
|||
default:
|
||||
myTypeface = Typeface.createFromAsset(getAssets(), "fonts/manroperegular.ttf");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
toolbarTitle.setTypeface(myTypeface);
|
||||
|
@ -191,12 +189,6 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
|||
@Override
|
||||
public void onDrawerOpened(@NonNull View drawerView) {
|
||||
|
||||
if(tinyDB.getBoolean("noConnection")) {
|
||||
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
tinyDB.putBoolean("noConnection", false);
|
||||
}
|
||||
|
||||
String userEmailNav = tinyDB.getString("userEmail");
|
||||
String userFullNameNav = tinyDB.getString("userFullname");
|
||||
String userAvatarNav = tinyDB.getString("userAvatar");
|
||||
|
@ -418,21 +410,24 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
|
|||
}
|
||||
}
|
||||
|
||||
if(!connToInternet) {
|
||||
handler.postDelayed(() -> {
|
||||
|
||||
if(!tinyDB.getBoolean("noConnection")) {
|
||||
boolean connToInternet = AppUtil.hasNetworkConnection(appCtx);
|
||||
if(!connToInternet) {
|
||||
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
if(!tinyDB.getBoolean("noConnection")) {
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
}
|
||||
tinyDB.putBoolean("noConnection", true);
|
||||
}
|
||||
else {
|
||||
|
||||
tinyDB.putBoolean("noConnection", true);
|
||||
}
|
||||
else {
|
||||
|
||||
loadUserInfo(instanceToken, loginUid);
|
||||
giteaVersion();
|
||||
tinyDB.putBoolean("noConnection", false);
|
||||
}
|
||||
loadUserInfo(instanceToken, loginUid);
|
||||
giteaVersion();
|
||||
tinyDB.putBoolean("noConnection", false);
|
||||
}
|
||||
Log.e("Network status is: ", String.valueOf(connToInternet));
|
||||
}, 1500);
|
||||
|
||||
// Changelog popup
|
||||
int versionCode = AppUtil.getAppBuildNo(appCtx);
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
import com.google.android.material.tabs.TabLayoutMediator;
|
||||
import org.gitnex.tea4j.models.OrgPermissions;
|
||||
import org.gitnex.tea4j.models.Teams;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.ActivityOrgTeamInfoBinding;
|
||||
import org.mian.gitnex.fragments.BottomSheetOrganizationTeamsFragment;
|
||||
import org.mian.gitnex.fragments.OrganizationTeamInfoMembersFragment;
|
||||
import org.mian.gitnex.fragments.OrganizationTeamInfoPermissionsFragment;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.structs.BottomSheetListener;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class OrganizationTeamInfoActivity extends BaseActivity implements BottomSheetListener {
|
||||
|
||||
private ActivityOrgTeamInfoBinding binding;
|
||||
private Teams team;
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
binding = ActivityOrgTeamInfoBinding.inflate(getLayoutInflater());
|
||||
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.toolbar);
|
||||
|
||||
team = (Teams) getIntent().getSerializableExtra("team");
|
||||
|
||||
if(team.getName() != null && !team.getName().isEmpty()) {
|
||||
binding.toolbarTitle.setText(team.getName());
|
||||
}
|
||||
else {
|
||||
binding.toolbarTitle.setText(R.string.orgTeamMembers);
|
||||
}
|
||||
|
||||
binding.close.setOnClickListener(view -> finish());
|
||||
binding.pager.setAdapter(new FragmentStateAdapter(getSupportFragmentManager(), getLifecycle()) {
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment createFragment(int position) {
|
||||
switch(position) {
|
||||
case 0:
|
||||
return OrganizationTeamInfoMembersFragment.newInstance(team);
|
||||
case 1:
|
||||
return OrganizationTeamInfoPermissionsFragment.newInstance(team);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return 2;
|
||||
}
|
||||
});
|
||||
|
||||
new TabLayoutMediator(binding.tabs, binding.pager, (tab, position) -> {
|
||||
TextView textView = (TextView) LayoutInflater.from(ctx).inflate(R.layout.layout_tab_text, null);
|
||||
|
||||
switch(position) {
|
||||
case 0:
|
||||
textView.setText(R.string.orgTabMembers);
|
||||
break;
|
||||
case 1:
|
||||
textView.setText(R.string.teamPermissions);
|
||||
break;
|
||||
}
|
||||
|
||||
tab.setCustomView(textView);
|
||||
}).attach();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
|
||||
if(tinyDb.getBoolean("teamActionFlag")) {
|
||||
tinyDb.putBoolean("teamActionFlag", false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
OrgPermissions permissions = (OrgPermissions) getIntent().getSerializableExtra("permissions");
|
||||
if(permissions == null || permissions.isOwner()) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
|
||||
if(id == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
else if(id == R.id.genericMenu) {
|
||||
BottomSheetOrganizationTeamsFragment bottomSheet = new BottomSheetOrganizationTeamsFragment();
|
||||
bottomSheet.show(getSupportFragmentManager(), "orgTeamsBottomSheet");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onButtonClicked(String text) {
|
||||
if("newMember".equals(text)) {
|
||||
Intent intent = new Intent(OrganizationTeamInfoActivity.this, AddNewTeamMemberActivity.class);
|
||||
intent.putExtra("team", team);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
package org.mian.gitnex.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import org.gitnex.tea4j.models.OrgPermissions;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.UserGridAdapter;
|
||||
import org.mian.gitnex.databinding.ActivityOrgTeamMembersBinding;
|
||||
import org.mian.gitnex.fragments.BottomSheetOrganizationTeamsFragment;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.structs.BottomSheetListener;
|
||||
import org.mian.gitnex.viewmodels.TeamMembersByOrgViewModel;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class OrganizationTeamMembersActivity extends BaseActivity implements BottomSheetListener {
|
||||
|
||||
private TextView noDataMembers;
|
||||
private View.OnClickListener onClickListener;
|
||||
private UserGridAdapter adapter;
|
||||
private GridView mGridView;
|
||||
private ProgressBar progressBar;
|
||||
|
||||
private String teamId;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityOrgTeamMembersBinding activityOrgTeamMembersBinding = ActivityOrgTeamMembersBinding.inflate(getLayoutInflater());
|
||||
setContentView(activityOrgTeamMembersBinding.getRoot());
|
||||
|
||||
Toolbar toolbar = activityOrgTeamMembersBinding.toolbar;
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ImageView closeActivity = activityOrgTeamMembersBinding.close;
|
||||
TextView toolbarTitle = activityOrgTeamMembersBinding.toolbarTitle;
|
||||
noDataMembers = activityOrgTeamMembersBinding.noDataMembers;
|
||||
mGridView = activityOrgTeamMembersBinding.gridView;
|
||||
progressBar = activityOrgTeamMembersBinding.progressBar;
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
|
||||
if(getIntent().getStringExtra("teamTitle") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamTitle")).equals("")) {
|
||||
|
||||
toolbarTitle.setText(getIntent().getStringExtra("teamTitle"));
|
||||
}
|
||||
else {
|
||||
|
||||
toolbarTitle.setText(R.string.orgTeamMembers);
|
||||
}
|
||||
|
||||
if(getIntent().getStringExtra("teamId") != null && !Objects.requireNonNull(getIntent().getStringExtra("teamId")).equals("")){
|
||||
|
||||
teamId = getIntent().getStringExtra("teamId");
|
||||
}
|
||||
else {
|
||||
|
||||
teamId = "0";
|
||||
}
|
||||
|
||||
assert teamId != null;
|
||||
fetchDataAsync(Authorization.get(ctx), Integer.parseInt(teamId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
|
||||
super.onResume();
|
||||
TinyDB tinyDb = TinyDB.getInstance(appCtx);
|
||||
|
||||
if(tinyDb.getBoolean("teamActionFlag")) {
|
||||
|
||||
fetchDataAsync(Authorization.get(ctx), Integer.parseInt(teamId));
|
||||
tinyDb.putBoolean("teamActionFlag", false);
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchDataAsync(String instanceToken, int teamId) {
|
||||
|
||||
TeamMembersByOrgViewModel teamMembersModel = new ViewModelProvider(this).get(TeamMembersByOrgViewModel.class);
|
||||
|
||||
teamMembersModel.getMembersByOrgList(instanceToken, teamId, ctx, noDataMembers, progressBar).observe(this, teamMembersListMain -> {
|
||||
|
||||
adapter = new UserGridAdapter(ctx, teamMembersListMain);
|
||||
|
||||
if(adapter.getCount() > 0) {
|
||||
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataMembers.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
adapter.notifyDataSetChanged();
|
||||
mGridView.setAdapter(adapter);
|
||||
noDataMembers.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
progressBar.setVisibility(View.GONE);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
if(((OrgPermissions) getIntent().getSerializableExtra("permissions")).isOwner()) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
int id = item.getItemId();
|
||||
|
||||
if(id == android.R.id.home) {
|
||||
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
else if(id == R.id.genericMenu) {
|
||||
|
||||
BottomSheetOrganizationTeamsFragment bottomSheet = new BottomSheetOrganizationTeamsFragment();
|
||||
bottomSheet.show(getSupportFragmentManager(), "orgTeamsBottomSheet");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onButtonClicked(String text) {
|
||||
|
||||
if("newMember".equals(text)) {
|
||||
|
||||
Intent intent = new Intent(OrganizationTeamMembersActivity.this, AddNewTeamMemberActivity.class);
|
||||
intent.putExtra("teamId", teamId);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
onClickListener = view -> finish();
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
|
|||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -42,7 +41,6 @@ import retrofit2.Response;
|
|||
|
||||
public class RepoForksActivity extends BaseActivity {
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
private TextView noData;
|
||||
private ProgressBar progressBar;
|
||||
private final String TAG = "RepositoryForks";
|
||||
|
@ -74,9 +72,7 @@ public class RepoForksActivity extends BaseActivity {
|
|||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
TextView toolbar_title = activityRepoForksBinding.toolbarTitle;
|
||||
toolbar_title.setMovementMethod(new ScrollingMovementMethod());
|
||||
toolbar_title.setText(String.format("%s : %s", ctx.getResources().getString(R.string.infoTabRepoForksCount), repoName));
|
||||
activityRepoForksBinding.toolbarTitle.setText(ctx.getResources().getString(R.string.infoTabRepoForksCount));
|
||||
|
||||
ImageView closeActivity = activityRepoForksBinding.close;
|
||||
noData = activityRepoForksBinding.noData;
|
||||
|
@ -84,21 +80,20 @@ public class RepoForksActivity extends BaseActivity {
|
|||
progressBar = activityRepoForksBinding.progressBar;
|
||||
SwipeRefreshLayout swipeRefresh = activityRepoForksBinding.pullToRefresh;
|
||||
|
||||
initCloseListener();
|
||||
closeActivity.setOnClickListener(onClickListener);
|
||||
closeActivity.setOnClickListener(v -> {
|
||||
getIntent().removeExtra("repoFullNameForForks");
|
||||
finish();
|
||||
});
|
||||
|
||||
// if gitea is 1.12 or higher use the new limit (resultLimitNewGiteaInstances)
|
||||
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12")) {
|
||||
|
||||
resultLimit = Constants.resultLimitNewGiteaInstances;
|
||||
}
|
||||
|
||||
recyclerView = activityRepoForksBinding.recyclerView;
|
||||
forksList = new ArrayList<>();
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
|
||||
DividerItemDecoration.VERTICAL);
|
||||
recyclerView.addItemDecoration(dividerItemDecoration);
|
||||
recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL));
|
||||
|
||||
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
|
||||
|
@ -141,30 +136,24 @@ public class RepoForksActivity extends BaseActivity {
|
|||
assert response.body() != null;
|
||||
|
||||
if(response.body().size() > 0) {
|
||||
|
||||
forksList.clear();
|
||||
forksList.addAll(response.body());
|
||||
adapter.notifyDataChanged();
|
||||
noData.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
forksList.clear();
|
||||
adapter.notifyDataChanged();
|
||||
noData.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
Log.e(TAG, String.valueOf(response.code()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<UserRepositories>> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e(TAG, t.toString());
|
||||
}
|
||||
});
|
||||
|
@ -193,27 +182,21 @@ public class RepoForksActivity extends BaseActivity {
|
|||
assert result != null;
|
||||
|
||||
if(result.size() > 0) {
|
||||
|
||||
pageSize = result.size();
|
||||
forksList.addAll(result);
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
adapter.setMoreDataAvailable(false);
|
||||
}
|
||||
|
||||
adapter.notifyDataChanged();
|
||||
progressLoadMore.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
Log.e(TAG, String.valueOf(response.code()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<UserRepositories>> call, @NonNull Throwable t) {
|
||||
|
||||
Log.e(TAG, t.toString());
|
||||
}
|
||||
|
||||
|
@ -235,44 +218,31 @@ public class RepoForksActivity extends BaseActivity {
|
|||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
|
||||
filter(newText);
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
private void filter(String text) {
|
||||
|
||||
List<UserRepositories> arr = new ArrayList<>();
|
||||
List<UserRepositories> userRepositories = new ArrayList<>();
|
||||
|
||||
for(UserRepositories d : forksList) {
|
||||
if(d.getName().toLowerCase().contains(text) ||
|
||||
d.getDescription().toLowerCase().contains(text)) {
|
||||
|
||||
if(d.getName().toLowerCase().contains(text) || d.getDescription().toLowerCase().contains(text)) {
|
||||
|
||||
arr.add(d);
|
||||
userRepositories.add(d);
|
||||
}
|
||||
}
|
||||
|
||||
adapter.updateList(arr);
|
||||
}
|
||||
|
||||
private void initCloseListener() {
|
||||
|
||||
onClickListener = view -> {
|
||||
|
||||
getIntent().removeExtra("repoFullNameForForks");
|
||||
finish();
|
||||
};
|
||||
adapter.updateList(userRepositories);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public class CollaboratorsAdapter extends BaseAdapter {
|
|||
@Override
|
||||
public View getView(int position, View finalView, ViewGroup parent) {
|
||||
|
||||
ViewHolder viewHolder = null;
|
||||
ViewHolder viewHolder;
|
||||
|
||||
if (finalView == null) {
|
||||
|
||||
|
|
|
@ -1,25 +1,22 @@
|
|||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import org.gitnex.tea4j.models.Commits;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.ClickListener;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
|
@ -48,8 +45,7 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
|
||||
if(viewType == TYPE_LOAD) {
|
||||
return new CommitsHolder(inflater.inflate(R.layout.list_commits, parent, false));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
|
||||
}
|
||||
}
|
||||
|
@ -72,56 +68,116 @@ public class CommitsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
|
||||
if(commitsList.get(position).getSha() != null) {
|
||||
return TYPE_LOAD;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
|
||||
return commitsList.size();
|
||||
}
|
||||
|
||||
class CommitsHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
TextView commitTitle;
|
||||
TextView commitCommitter;
|
||||
TextView commitDate;
|
||||
Button commitHtmlUrl;
|
||||
View rootView;
|
||||
|
||||
TextView commitSubject;
|
||||
TextView commitBody;
|
||||
TextView commitAuthorAndCommitter;
|
||||
ImageView commitAuthorAvatar;
|
||||
ImageView commitCommitterAvatar;
|
||||
TextView commitSha;
|
||||
|
||||
CommitsHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
commitTitle = itemView.findViewById(R.id.commitTitleVw);
|
||||
commitCommitter = itemView.findViewById(R.id.commitCommitterVw);
|
||||
commitDate = itemView.findViewById(R.id.commitDateVw);
|
||||
commitHtmlUrl = itemView.findViewById(R.id.commitHtmlUrlVw);
|
||||
rootView = itemView;
|
||||
|
||||
commitSubject = itemView.findViewById(R.id.commitSubject);
|
||||
commitBody = itemView.findViewById(R.id.commitBody);
|
||||
commitAuthorAndCommitter = itemView.findViewById(R.id.commitAuthorAndCommitter);
|
||||
commitAuthorAvatar = itemView.findViewById(R.id.commitAuthorAvatar);
|
||||
commitCommitterAvatar = itemView.findViewById(R.id.commitCommitterAvatar);
|
||||
commitSha = itemView.findViewById(R.id.commitSha);
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
void bindData(Commits commitsModel) {
|
||||
|
||||
final TinyDB tinyDb = TinyDB.getInstance(context);
|
||||
Locale locale = context.getResources().getConfiguration().locale;
|
||||
final String timeFormat = tinyDb.getString("dateFormat");
|
||||
String[] commitMessageParts = commitsModel.getCommit().getMessage().split("(\r\n|\n)", 2);
|
||||
|
||||
commitTitle.setText(EmojiParser.parseToUnicode(commitsModel.getCommit().getMessage()));
|
||||
commitCommitter.setText(context.getString(R.string.commitCommittedBy, commitsModel.getCommit().getCommitter().getName()));
|
||||
commitDate.setText(TimeHelper.formatTime(commitsModel.getCommit().getCommitter().getDate(), locale, timeFormat, context));
|
||||
|
||||
if(timeFormat.equals("pretty")) {
|
||||
commitDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(commitsModel.getCommit().getCommitter().getDate()), context));
|
||||
if(commitMessageParts.length > 1 && !commitMessageParts[1].trim().isEmpty()) {
|
||||
commitBody.setVisibility(View.VISIBLE);
|
||||
commitSubject.setText(EmojiParser.parseToUnicode(commitMessageParts[0].trim()));
|
||||
commitBody.setText(EmojiParser.parseToUnicode(commitMessageParts[1].trim()));
|
||||
} else {
|
||||
commitSubject.setText(EmojiParser.parseToUnicode(commitMessageParts[0].trim()));
|
||||
commitBody.setVisibility(View.GONE);
|
||||
}
|
||||
commitHtmlUrl.setOnClickListener(v -> AppUtil.openUrlInBrowser(context, commitsModel.getHtml_url()));
|
||||
}
|
||||
|
||||
if(commitsModel.getCommitter().getId() != commitsModel.getAuthor().getId()) {
|
||||
commitAuthorAndCommitter.setText(HtmlCompat.fromHtml(context
|
||||
.getString(R.string.commitAuthoredByAndCommittedByWhen, commitsModel.getAuthor().getUsername(), commitsModel.getCommitter().getUsername(),
|
||||
TimeHelper
|
||||
.formatTime(commitsModel.getCommit().getCommitter().getDate(), context.getResources().getConfiguration().locale, "pretty",
|
||||
context)), HtmlCompat.FROM_HTML_MODE_COMPACT));
|
||||
} else {
|
||||
commitAuthorAndCommitter.setText(HtmlCompat.fromHtml(context
|
||||
.getString(R.string.commitCommittedByWhen, commitsModel.getCommitter().getUsername(),
|
||||
TimeHelper
|
||||
.formatTime(commitsModel.getCommit().getCommitter().getDate(), context.getResources().getConfiguration().locale, "pretty",
|
||||
context)), HtmlCompat.FROM_HTML_MODE_COMPACT));
|
||||
|
||||
}
|
||||
|
||||
if(commitsModel.getAuthor().getAvatar_url() != null &&
|
||||
!commitsModel.getAuthor().getAvatar_url().isEmpty()) {
|
||||
|
||||
commitAuthorAvatar.setVisibility(View.VISIBLE);
|
||||
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
PicassoService.getInstance(context).get()
|
||||
.load(commitsModel.getAuthor().getAvatar_url())
|
||||
.placeholder(R.drawable.loader_animated)
|
||||
.transform(new RoundedTransformation(imgRadius, 0))
|
||||
.resize(120, 120)
|
||||
.centerCrop().into(commitAuthorAvatar);
|
||||
|
||||
} else {
|
||||
commitAuthorAvatar.setImageDrawable(null);
|
||||
commitAuthorAvatar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(!commitsModel.getAuthor().getLogin().equals(commitsModel.getCommitter().getLogin()) &&
|
||||
commitsModel.getCommitter().getAvatar_url() != null &&
|
||||
!commitsModel.getCommitter().getAvatar_url().isEmpty()) {
|
||||
|
||||
commitCommitterAvatar.setVisibility(View.VISIBLE);
|
||||
|
||||
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
|
||||
|
||||
PicassoService.getInstance(context).get()
|
||||
.load(commitsModel.getCommitter().getAvatar_url())
|
||||
.placeholder(R.drawable.loader_animated)
|
||||
.transform(new RoundedTransformation(imgRadius, 0))
|
||||
.resize(120, 120)
|
||||
.centerCrop().into(commitCommitterAvatar);
|
||||
|
||||
} else {
|
||||
commitCommitterAvatar.setImageDrawable(null);
|
||||
commitCommitterAvatar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
commitSha.setText(commitsModel.getSha().substring(0, Math.min(commitsModel.getSha().length(), 10)));
|
||||
rootView.setOnClickListener(v -> AppUtil.openUrlInBrowser(context, commitsModel.getHtml_url()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class LoadHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
LoadHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
|
151
app/src/main/java/org/mian/gitnex/adapters/DiffAdapter.java
Normal file
151
app/src/main/java/org/mian/gitnex/adapters/DiffAdapter.java
Normal file
|
@ -0,0 +1,151 @@
|
|||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.TextView;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Author opyale
|
||||
*/
|
||||
|
||||
public class DiffAdapter extends BaseAdapter {
|
||||
|
||||
private final Context context;
|
||||
private final FragmentManager fragmentManager;
|
||||
private final List<String> lines;
|
||||
|
||||
private final List<Integer> selectedLines;
|
||||
private final Typeface typeface;
|
||||
|
||||
private static int COLOR_ADDED;
|
||||
private static int COLOR_REMOVED;
|
||||
private static int COLOR_NORMAL;
|
||||
private static int COLOR_SELECTED;
|
||||
private static int COLOR_FONT;
|
||||
|
||||
public DiffAdapter(Context context, FragmentManager fragmentManager, List<String> lines) {
|
||||
|
||||
this.context = context;
|
||||
this.fragmentManager = fragmentManager;
|
||||
this.lines = lines;
|
||||
|
||||
selectedLines = new ArrayList<>();
|
||||
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf");
|
||||
|
||||
COLOR_ADDED = AppUtil.getColorFromAttribute(context, R.attr.diffAddedColor);
|
||||
COLOR_REMOVED = AppUtil.getColorFromAttribute(context, R.attr.diffRemovedColor);
|
||||
COLOR_NORMAL = AppUtil.getColorFromAttribute(context, R.attr.primaryBackgroundColor);
|
||||
COLOR_SELECTED = AppUtil.getColorFromAttribute(context, R.attr.diffSelectedColor);
|
||||
COLOR_FONT = AppUtil.getColorFromAttribute(context, R.attr.inputTextColor);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return lines.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return lines.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
|
||||
if(convertView == null) {
|
||||
|
||||
TextView textView = new TextView(context);
|
||||
|
||||
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
textView.setTextColor(COLOR_FONT);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
textView.setPadding(15, 0, 15, 0);
|
||||
textView.setTypeface(typeface);
|
||||
|
||||
convertView = textView;
|
||||
|
||||
}
|
||||
|
||||
convertView.setOnClickListener(v -> {
|
||||
|
||||
if(selectedLines.contains(position)) {
|
||||
|
||||
selectedLines.remove((Object) position);
|
||||
v.setBackgroundColor(getLineColor(lines.get(position)));
|
||||
} else {
|
||||
|
||||
selectedLines.add(position);
|
||||
v.setBackgroundColor(COLOR_SELECTED);
|
||||
}
|
||||
});
|
||||
|
||||
convertView.setOnLongClickListener(v -> {
|
||||
|
||||
if(selectedLines.contains(position)) {
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("```\n");
|
||||
|
||||
for(Integer selectedLine : selectedLines.stream().sorted().collect(Collectors.toList())) {
|
||||
stringBuilder.append(lines.get(selectedLine));
|
||||
stringBuilder.append("\n");
|
||||
}
|
||||
|
||||
stringBuilder.append("```\n\n");
|
||||
selectedLines.clear();
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("commentBody", stringBuilder.toString());
|
||||
bundle.putBoolean("cursorToEnd", true);
|
||||
|
||||
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
String line = lines.get(position);
|
||||
|
||||
int backgroundColor = selectedLines.contains(position) ? COLOR_SELECTED : getLineColor(line);
|
||||
|
||||
convertView.setBackgroundColor(backgroundColor);
|
||||
((TextView) convertView).setText(line);
|
||||
|
||||
return convertView;
|
||||
|
||||
}
|
||||
|
||||
private int getLineColor(String line) {
|
||||
|
||||
if(line.length() == 0) {
|
||||
return COLOR_NORMAL;
|
||||
}
|
||||
|
||||
switch(line.charAt(0)) {
|
||||
case '+': return COLOR_ADDED;
|
||||
case '-': return COLOR_REMOVED;
|
||||
|
||||
default: return COLOR_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.TextView;
|
||||
import org.gitnex.tea4j.models.FileDiffView;
|
||||
import org.mian.gitnex.R;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
|
||||
public class DiffFilesAdapter extends BaseAdapter {
|
||||
|
||||
private static final Pattern statisticsPattern = Pattern.compile("(\\d+).*?,.*?(\\d+)");
|
||||
|
||||
private final Context context;
|
||||
private final List<FileDiffView> fileDiffViews;
|
||||
|
||||
public DiffFilesAdapter(Context context, List<FileDiffView> fileDiffViews) {
|
||||
this.context = context;
|
||||
this.fileDiffViews = fileDiffViews;
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
private final TextView fileName;
|
||||
private final TextView fileStatistics;
|
||||
|
||||
public ViewHolder(TextView fileName, TextView fileStatistics) {
|
||||
this.fileName = fileName;
|
||||
this.fileStatistics = fileStatistics;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return fileDiffViews.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return fileDiffViews.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
|
||||
ViewHolder viewHolder;
|
||||
|
||||
if(convertView == null) {
|
||||
convertView = LayoutInflater.from(context).inflate(R.layout.list_diff_files, parent, false);
|
||||
|
||||
viewHolder = new ViewHolder(
|
||||
convertView.findViewById(R.id.fileName),
|
||||
convertView.findViewById(R.id.fileStatistics)
|
||||
);
|
||||
|
||||
convertView.setTag(viewHolder);
|
||||
} else {
|
||||
viewHolder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
FileDiffView fileDiffView = fileDiffViews.get(position);
|
||||
|
||||
viewHolder.fileName.setText(fileDiffView.getFileName());
|
||||
|
||||
Matcher matcher = statisticsPattern.matcher(fileDiffView.getFileInfo());
|
||||
|
||||
if(matcher.find() && matcher.groupCount() == 2) {
|
||||
viewHolder.fileStatistics.setText(context.getString(R.string.diffStatistics, matcher.group(1), matcher.group(2)));
|
||||
} else {
|
||||
viewHolder.fileStatistics.setText(fileDiffView.getFileInfo());
|
||||
}
|
||||
|
||||
return convertView;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,252 +0,0 @@
|
|||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import org.gitnex.tea4j.models.FileDiffView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.views.DiffTextView;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
/**
|
||||
* Author opyale
|
||||
*/
|
||||
|
||||
public class FilesDiffAdapter extends BaseAdapter {
|
||||
|
||||
private static Map<Long, View> selectedViews;
|
||||
private static final int MAXIMUM_LINES = 5000;
|
||||
|
||||
private static int COLOR_ADDED;
|
||||
private static int COLOR_REMOVED;
|
||||
private static int COLOR_NORMAL;
|
||||
private static int COLOR_SELECTED;
|
||||
private static int COLOR_FONT;
|
||||
|
||||
private final Context context;
|
||||
private final FragmentManager fragmentManager;
|
||||
private final List<FileDiffView> fileDiffViews;
|
||||
|
||||
public FilesDiffAdapter(Context context, FragmentManager fragmentManager, List<FileDiffView> fileDiffViews) {
|
||||
|
||||
this.context = context;
|
||||
this.fragmentManager = fragmentManager;
|
||||
this.fileDiffViews = fileDiffViews;
|
||||
|
||||
selectedViews = new ConcurrentSkipListMap<>();
|
||||
|
||||
COLOR_ADDED = AppUtil.getColorFromAttribute(context, R.attr.diffAddedColor);
|
||||
COLOR_REMOVED = AppUtil.getColorFromAttribute(context, R.attr.diffRemovedColor);
|
||||
COLOR_NORMAL = AppUtil.getColorFromAttribute(context, R.attr.primaryBackgroundColor);
|
||||
COLOR_SELECTED = AppUtil.getColorFromAttribute(context, R.attr.diffSelectedColor);
|
||||
COLOR_FONT = AppUtil.getColorFromAttribute(context, R.attr.inputTextColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
|
||||
return fileDiffViews.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
|
||||
return fileDiffViews.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
@SuppressLint({"ViewHolder", "InflateParams"})
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
|
||||
convertView = LayoutInflater.from(context).inflate(R.layout.list_files_diffs, null, false);
|
||||
|
||||
TextView headerFileName = convertView.findViewById(R.id.headerFileName);
|
||||
TextView headerFileInfo = convertView.findViewById(R.id.headerFileInfo);
|
||||
ImageView footerImage = convertView.findViewById(R.id.footerImage);
|
||||
LinearLayout diffStats = convertView.findViewById(R.id.diff_stats);
|
||||
LinearLayout diffLines = convertView.findViewById(R.id.diffLines);
|
||||
|
||||
FileDiffView data = (FileDiffView) getItem(position);
|
||||
headerFileName.setText(data.getFileName());
|
||||
|
||||
if(data.isFileBinary()) {
|
||||
|
||||
diffStats.setVisibility(View.GONE);
|
||||
diffLines.addView(getMessageView(context.getResources().getString(R.string.binaryFileError)));
|
||||
}
|
||||
else {
|
||||
|
||||
diffStats.setVisibility(View.VISIBLE);
|
||||
headerFileInfo.setText(data.getFileInfo());
|
||||
|
||||
String[] codeLines = getLines(data.toString());
|
||||
|
||||
if(MAXIMUM_LINES > codeLines.length) {
|
||||
|
||||
for(int l=0; l<codeLines.length; l++) {
|
||||
|
||||
if(codeLines[l].length() > 0) {
|
||||
|
||||
int uniquePosition = l + (position * MAXIMUM_LINES);
|
||||
|
||||
DiffTextView diffTextView = new DiffTextView(context);
|
||||
|
||||
diffTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
|
||||
diffTextView.setPadding(15, 2, 15, 2);
|
||||
diffTextView.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/sourcecodeproregular.ttf"));
|
||||
diffTextView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
diffTextView.setPosition(uniquePosition);
|
||||
|
||||
boolean isSelected = false;
|
||||
|
||||
for(View view : selectedViews.values()) {
|
||||
|
||||
if(((DiffTextView) view).getPosition() == uniquePosition) {
|
||||
|
||||
diffTextView.setBackgroundColor(COLOR_SELECTED);
|
||||
isSelected = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(codeLines[l].startsWith("+")) {
|
||||
|
||||
diffTextView.setText(codeLines[l]);
|
||||
diffTextView.setTextColor(COLOR_FONT);
|
||||
|
||||
if(!isSelected) {
|
||||
|
||||
diffTextView.setInitialBackgroundColor(COLOR_ADDED);
|
||||
}
|
||||
|
||||
}
|
||||
else if(codeLines[l].startsWith("-")) {
|
||||
|
||||
diffTextView.setText(codeLines[l]);
|
||||
diffTextView.setTextColor(COLOR_FONT);
|
||||
|
||||
if(!isSelected) {
|
||||
|
||||
diffTextView.setInitialBackgroundColor(COLOR_REMOVED);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
diffTextView.setText(codeLines[l]);
|
||||
diffTextView.setTextColor(COLOR_FONT);
|
||||
|
||||
if(!isSelected) {
|
||||
|
||||
diffTextView.setInitialBackgroundColor(COLOR_NORMAL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
diffTextView.setOnClickListener(v -> {
|
||||
|
||||
if(((DiffTextView) v).getCurrentBackgroundColor() != COLOR_SELECTED) {
|
||||
|
||||
selectedViews.put(((DiffTextView) v).getPosition(), v);
|
||||
v.setBackgroundColor(COLOR_SELECTED);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
selectedViews.remove(((DiffTextView) v).getPosition());
|
||||
v.setBackgroundColor(((DiffTextView) v).getInitialBackgroundColor());
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
diffTextView.setOnLongClickListener(v -> {
|
||||
|
||||
if(((DiffTextView) v).getCurrentBackgroundColor() == COLOR_SELECTED) {
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("```\n");
|
||||
|
||||
for(View view : selectedViews.values()) {
|
||||
|
||||
stringBuilder.append(((DiffTextView) view).getText());
|
||||
stringBuilder.append("\n");
|
||||
}
|
||||
|
||||
stringBuilder.append("```\n\n");
|
||||
|
||||
selectedViews.clear();
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("commentBody", stringBuilder.toString());
|
||||
bundle.putBoolean("cursorToEnd", true);
|
||||
|
||||
BottomSheetReplyFragment.newInstance(bundle).show(fragmentManager, "replyBottomSheet");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
diffLines.addView(diffTextView);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
diffLines.addView(getMessageView(context.getResources().getString(R.string.fileTooLarge)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return convertView;
|
||||
|
||||
}
|
||||
|
||||
private TextView getMessageView(String message) {
|
||||
|
||||
TextView textView = new TextView(context);
|
||||
|
||||
textView.setTextColor(COLOR_FONT);
|
||||
textView.setBackgroundColor(COLOR_NORMAL);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
textView.setPadding(15, 15, 15, 15);
|
||||
textView.setTypeface(Typeface.DEFAULT);
|
||||
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
textView.setText(message);
|
||||
|
||||
return textView;
|
||||
}
|
||||
|
||||
private String[] getLines(String content) {
|
||||
|
||||
return content.split("\\R");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -140,12 +140,11 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdap
|
|||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Handler handler = new Handler();
|
||||
handler.postDelayed(() -> {
|
||||
reactionSpinner.setOnLoadingFinishedListener(() -> {
|
||||
linearLayout.removeView(loadReactions);
|
||||
reactionSpinner.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 160));
|
||||
linearLayout.addView(reactionSpinner);
|
||||
}, 2500);
|
||||
});
|
||||
|
||||
commentMenuEdit.setOnClickListener(v1 -> {
|
||||
Bundle bundle = new Bundle();
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.mian.gitnex.adapters;
|
|||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -11,6 +12,7 @@ import android.widget.TextView;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.core.widget.ImageViewCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.gitnex.tea4j.models.NotificationThread;
|
||||
|
@ -18,6 +20,7 @@ import org.mian.gitnex.R;
|
|||
import org.mian.gitnex.database.api.BaseApi;
|
||||
import org.mian.gitnex.database.api.RepositoriesApi;
|
||||
import org.mian.gitnex.database.models.Repository;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -89,11 +92,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||
private final LinearLayout frame;
|
||||
private final TextView subject;
|
||||
private final TextView repository;
|
||||
private final ImageView typePr;
|
||||
private final ImageView typeIssue;
|
||||
private final ImageView typeRepo;
|
||||
private final ImageView typeCommit;
|
||||
private final ImageView typeUnknown;
|
||||
private final ImageView type;
|
||||
private ImageView pinned;
|
||||
private final ImageView more;
|
||||
|
||||
|
@ -103,11 +102,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||
frame = itemView.findViewById(R.id.frame);
|
||||
subject = itemView.findViewById(R.id.subject);
|
||||
repository = itemView.findViewById(R.id.repository);
|
||||
typePr = itemView.findViewById(R.id.typePr);
|
||||
typeIssue = itemView.findViewById(R.id.typeIssue);
|
||||
typeRepo = itemView.findViewById(R.id.typeRepo);
|
||||
typeCommit = itemView.findViewById(R.id.typeCommit);
|
||||
typeUnknown = itemView.findViewById(R.id.typeUnknown);
|
||||
type = itemView.findViewById(R.id.type);
|
||||
pinned = itemView.findViewById(R.id.pinned);
|
||||
more = itemView.findViewById(R.id.more);
|
||||
}
|
||||
|
@ -138,41 +133,39 @@ public class NotificationsAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||
pinned.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
switch(notificationThread.getSubject().getType()) {
|
||||
case "Pull":
|
||||
typePr.setVisibility(View.VISIBLE);
|
||||
typeIssue.setVisibility(View.GONE);
|
||||
typeRepo.setVisibility(View.GONE);
|
||||
typeCommit.setVisibility(View.GONE);
|
||||
typeUnknown.setVisibility(View.GONE);
|
||||
switch(notificationThread.getSubject().getType().toLowerCase()) {
|
||||
|
||||
case "pull":
|
||||
type.setImageResource(R.drawable.ic_pull_request);
|
||||
break;
|
||||
case "Issue":
|
||||
typePr.setVisibility(View.GONE);
|
||||
typeRepo.setVisibility(View.GONE);
|
||||
typeCommit.setVisibility(View.GONE);
|
||||
typeIssue.setVisibility(View.VISIBLE);
|
||||
typeUnknown.setVisibility(View.GONE);
|
||||
case "issue":
|
||||
type.setImageResource(R.drawable.ic_issue);
|
||||
break;
|
||||
case "Repository":
|
||||
typeUnknown.setVisibility(View.GONE);
|
||||
typeIssue.setVisibility(View.GONE);
|
||||
typePr.setVisibility(View.GONE);
|
||||
typeRepo.setVisibility(View.VISIBLE);
|
||||
typeCommit.setVisibility(View.GONE);
|
||||
case "commit":
|
||||
type.setImageResource(R.drawable.ic_commit);
|
||||
break;
|
||||
case "Commit":
|
||||
typeUnknown.setVisibility(View.GONE);
|
||||
typeIssue.setVisibility(View.GONE);
|
||||
typePr.setVisibility(View.GONE);
|
||||
typeRepo.setVisibility(View.GONE);
|
||||
typeCommit.setVisibility(View.VISIBLE);
|
||||
case "repository":
|
||||
type.setImageResource(R.drawable.ic_repo);
|
||||
break;
|
||||
|
||||
default:
|
||||
typePr.setVisibility(View.GONE);
|
||||
typeRepo.setVisibility(View.GONE);
|
||||
typeCommit.setVisibility(View.GONE);
|
||||
typeIssue.setVisibility(View.GONE);
|
||||
typeUnknown.setVisibility(View.VISIBLE);
|
||||
type.setImageResource(R.drawable.ic_question);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
switch(notificationThread.getSubject().getState().toLowerCase()) {
|
||||
|
||||
case "closed":
|
||||
ImageViewCompat.setImageTintList(type, ColorStateList.valueOf(context.getResources().getColor(R.color.iconIssuePrClosedColor)));
|
||||
break;
|
||||
case "merged":
|
||||
ImageViewCompat.setImageTintList(type, ColorStateList.valueOf(context.getResources().getColor(R.color.iconPrMergedColor)));
|
||||
break;
|
||||
|
||||
default:
|
||||
case "open":
|
||||
ImageViewCompat.setImageTintList(type, ColorStateList.valueOf(AppUtil.getColorFromAttribute(context, R.attr.iconsColor)));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
|
||||
public class ReactionAuthorsAdapter extends RecyclerView.Adapter<ReactionAuthorsAdapter.ViewHolder> {
|
||||
|
||||
private final Context context;
|
||||
private final List<UserInfo> userInfos;
|
||||
|
||||
public ReactionAuthorsAdapter(Context context, List<UserInfo> userInfos) {
|
||||
this.context = context;
|
||||
this.userInfos = userInfos;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_reaction_authors, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
UserInfo userInfo = userInfos.get(position);
|
||||
|
||||
PicassoService.getInstance(context).get()
|
||||
.load(userInfo.getAvatar())
|
||||
.placeholder(R.drawable.loader_animated)
|
||||
.resize(240, 240)
|
||||
.transform(new RoundedTransformation(AppUtil.getPixelsFromDensity(context, 6), 0))
|
||||
.centerCrop().into(holder.authorAvatar);
|
||||
|
||||
if(userInfo.getFullname() == null || userInfo.getFullname().isEmpty()) {
|
||||
holder.authorFullName.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.authorFullName.setText(userInfo.getFullname());
|
||||
holder.authorFullName.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
holder.authorLogin.setText(userInfo.getLogin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return userInfos.size();
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private final ImageView authorAvatar;
|
||||
|
||||
private final TextView authorFullName;
|
||||
private final TextView authorLogin;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
|
||||
authorAvatar = itemView.findViewById(R.id.authorAvatar);
|
||||
authorFullName = itemView.findViewById(R.id.authorFullName);
|
||||
authorLogin = itemView.findViewById(R.id.authorLogin);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -24,6 +24,7 @@ import org.mian.gitnex.database.api.BaseApi;
|
|||
import org.mian.gitnex.database.api.RepositoriesApi;
|
||||
import org.mian.gitnex.database.models.Repository;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.ClickListener;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import org.mian.gitnex.helpers.TimeHelper;
|
||||
|
@ -64,8 +65,7 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
|
||||
if(viewType == TYPE_LOAD) {
|
||||
return new RepoForksAdapter.ForksHolder(inflater.inflate(R.layout.list_repositories, parent, false));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false));
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +139,6 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
repoName.setText(forksModel.getFullName().split("/")[1]);
|
||||
repoStars.setText(forksModel.getStars_count());
|
||||
|
||||
|
||||
ColorGenerator generator = ColorGenerator.MATERIAL;
|
||||
int color = generator.getColor(forksModel.getName());
|
||||
String firstCharacter = String.valueOf(forksModel.getFullName().charAt(0));
|
||||
|
@ -244,48 +243,31 @@ public class RepoForksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
//store if user is watching this repo
|
||||
{
|
||||
|
||||
final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token");
|
||||
RetrofitClient.getApiInterface(context)
|
||||
.checkRepoWatchStatus(Authorization.get(context), repoOwner, repoName)
|
||||
.enqueue(new Callback<WatchInfo>() {
|
||||
|
||||
WatchInfo watch = new WatchInfo();
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
|
||||
|
||||
Call<WatchInfo> call;
|
||||
if(response.isSuccessful() && response.body() != null) {
|
||||
|
||||
call = RetrofitClient.getApiInterface(context).checkRepoWatchStatus(token, repoOwner, repoName);
|
||||
|
||||
call.enqueue(new Callback<WatchInfo>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<WatchInfo> call, @NonNull retrofit2.Response<WatchInfo> response) {
|
||||
|
||||
if(response.isSuccessful()) {
|
||||
|
||||
assert response.body() != null;
|
||||
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
tinyDb.putBoolean("repoWatch", false);
|
||||
|
||||
if(response.code() != 404) {
|
||||
|
||||
Toasty.error(context, context.getString(R.string.genericApiStatusError));
|
||||
tinyDb.putBoolean("repoWatch", response.body().getSubscribed());
|
||||
} else {
|
||||
tinyDb.putBoolean("repoWatch", false);
|
||||
|
||||
if(response.code() != 404) {
|
||||
Toasty.error(context, context.getString(R.string.genericApiStatusError));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
|
||||
|
||||
tinyDb.putBoolean("repoWatch", false);
|
||||
Toasty.error(context, context.getString(R.string.genericApiStatusError));
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<WatchInfo> call, @NonNull Throwable t) {
|
||||
tinyDb.putBoolean("repoWatch", false);
|
||||
Toasty.error(context, context.getString(R.string.genericApiStatusError));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
context.startActivity(intent);
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package org.mian.gitnex.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.PicassoService;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.RoundedTransformation;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
|
||||
public class TeamMembersByOrgPreviewAdapter extends RecyclerView.Adapter<TeamMembersByOrgPreviewAdapter.ViewHolder> {
|
||||
|
||||
private final Context context;
|
||||
private final List<UserInfo> userData;
|
||||
|
||||
public TeamMembersByOrgPreviewAdapter(Context context, List<UserInfo> userInfo) {
|
||||
this.context = context;
|
||||
this.userData = userInfo;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(context).inflate(R.layout.list_members_by_org_preview, parent, false);
|
||||
return new ViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
UserInfo userInfo = userData.get(position);
|
||||
|
||||
PicassoService.getInstance(context).get()
|
||||
.load(userInfo.getAvatar())
|
||||
.placeholder(R.drawable.loader_animated)
|
||||
.transform(new RoundedTransformation(AppUtil.getPixelsFromDensity(context, 3), 0))
|
||||
.resize(120, 120)
|
||||
.centerCrop().into(holder.avatar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return userData.size();
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private final ImageView avatar;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
avatar = itemView.findViewById(R.id.avatar);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,15 +7,24 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.Filter;
|
||||
import android.widget.Filterable;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import org.gitnex.tea4j.models.OrgPermissions;
|
||||
import org.gitnex.tea4j.models.Teams;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.OrganizationTeamMembersActivity;
|
||||
import org.mian.gitnex.activities.OrganizationTeamInfoActivity;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
|
@ -30,33 +39,40 @@ public class TeamsByOrgAdapter extends RecyclerView.Adapter<TeamsByOrgAdapter.Or
|
|||
|
||||
static class OrgTeamsViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private Teams teams;
|
||||
private Teams team;
|
||||
|
||||
private OrgPermissions permissions;
|
||||
private final TextView teamTitle;
|
||||
private final TextView teamDescription;
|
||||
private final TextView teamPermission;
|
||||
private final LinearLayout membersPreviewFrame;
|
||||
|
||||
private final List<UserInfo> userInfos;
|
||||
private final TeamMembersByOrgPreviewAdapter adapter;
|
||||
|
||||
private OrgTeamsViewHolder(View itemView) {
|
||||
|
||||
super(itemView);
|
||||
|
||||
teamTitle = itemView.findViewById(R.id.teamTitle);
|
||||
teamDescription = itemView.findViewById(R.id.teamDescription);
|
||||
teamPermission = itemView.findViewById(R.id.teamPermission);
|
||||
membersPreviewFrame = itemView.findViewById(R.id.membersPreviewFrame);
|
||||
|
||||
RecyclerView membersPreview = itemView.findViewById(R.id.membersPreview);
|
||||
|
||||
userInfos = new ArrayList<>();
|
||||
adapter = new TeamMembersByOrgPreviewAdapter(itemView.getContext(), userInfos);
|
||||
|
||||
membersPreview.setLayoutManager(new LinearLayoutManager(itemView.getContext(), RecyclerView.HORIZONTAL, false));
|
||||
membersPreview.setAdapter(adapter);
|
||||
|
||||
itemView.setOnClickListener(v -> {
|
||||
|
||||
Context context = v.getContext();
|
||||
|
||||
Intent intent = new Intent(context, OrganizationTeamMembersActivity.class);
|
||||
intent.putExtra("teamTitle", teams.getName());
|
||||
intent.putExtra("teamId", String.valueOf(teams.getId()));
|
||||
Intent intent = new Intent(context, OrganizationTeamInfoActivity.class);
|
||||
intent.putExtra("team", team);
|
||||
intent.putExtra("permissions", permissions);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public TeamsByOrgAdapter(Context ctx, List<Teams> teamListMain, OrgPermissions permissions) {
|
||||
|
@ -78,19 +94,42 @@ public class TeamsByOrgAdapter extends RecyclerView.Adapter<TeamsByOrgAdapter.Or
|
|||
|
||||
Teams currentItem = teamList.get(position);
|
||||
|
||||
holder.teams = currentItem;
|
||||
holder.team = currentItem;
|
||||
holder.teamTitle.setText(currentItem.getName());
|
||||
holder.permissions = permissions;
|
||||
|
||||
if (!currentItem.getDescription().equals("")) {
|
||||
holder.membersPreviewFrame.setVisibility(View.GONE);
|
||||
holder.userInfos.clear();
|
||||
holder.adapter.notifyDataSetChanged();
|
||||
|
||||
RetrofitClient.getApiInterface(context)
|
||||
.getTeamMembersByOrg(Authorization.get(context), currentItem.getId())
|
||||
.enqueue(new Callback<List<UserInfo>>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<UserInfo>> call, @NonNull Response<List<UserInfo>> response) {
|
||||
if(response.isSuccessful() &&
|
||||
response.body() != null &&
|
||||
response.body().size() > 0) {
|
||||
|
||||
holder.membersPreviewFrame.setVisibility(View.VISIBLE);
|
||||
holder.userInfos.addAll(response.body().stream()
|
||||
.limit(Math.min(response.body().size(), 6))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
holder.adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onFailure(@NonNull Call<List<UserInfo>> call, @NonNull Throwable t) {}
|
||||
});
|
||||
|
||||
if (currentItem.getDescription() != null && !currentItem.getDescription().isEmpty()) {
|
||||
holder.teamDescription.setVisibility(View.VISIBLE);
|
||||
holder.teamDescription.setText(currentItem.getDescription());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
holder.teamDescription.setVisibility(View.GONE);
|
||||
holder.teamDescription.setText("");
|
||||
}
|
||||
holder.teamPermission.setText(context.getResources().getString(R.string.teamPermission, currentItem.getPermission()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -82,7 +82,7 @@ public class UserGridAdapter extends BaseAdapter implements Filterable {
|
|||
@Override
|
||||
public View getView(int position, View finalView, ViewGroup parent) {
|
||||
|
||||
UserGridAdapter.ViewHolder viewHolder = null;
|
||||
UserGridAdapter.ViewHolder viewHolder;
|
||||
|
||||
if (finalView == null) {
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package org.mian.gitnex.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -13,9 +11,11 @@ import androidx.annotation.Nullable;
|
|||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import org.gitnex.tea4j.models.NotificationThread;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.actions.NotificationsActions;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.BottomSheetNotificationsBinding;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.SimpleCallback;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
|
||||
/**
|
||||
|
@ -48,94 +48,55 @@ public class BottomSheetNotificationsFragment extends BottomSheetDialogFragment
|
|||
TextView markUnread = bottomSheetNotificationsBinding.markUnread;
|
||||
TextView markPinned = bottomSheetNotificationsBinding.markPinned;
|
||||
|
||||
NotificationsActions notificationsActions = new NotificationsActions(context);
|
||||
Activity activity = requireActivity();
|
||||
|
||||
if(notificationThread.isPinned()) {
|
||||
|
||||
AppUtil.setMultiVisibility(View.GONE, markUnread, markPinned);
|
||||
} else if(notificationThread.isUnread()) {
|
||||
|
||||
markUnread.setVisibility(View.GONE);
|
||||
} else {
|
||||
|
||||
markRead.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
markPinned.setOnClickListener(v12 -> {
|
||||
markPinned.setOnClickListener(v12 ->
|
||||
RetrofitClient.getApiInterface(context)
|
||||
.markNotificationThreadAsRead(Authorization.get(context), notificationThread.getId(), "pinned")
|
||||
.enqueue((SimpleCallback<Void>) (call, voidResponse) -> {
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
try {
|
||||
|
||||
notificationsActions.setNotificationStatus(notificationThread, NotificationsActions.NotificationStatus.PINNED);
|
||||
activity.runOnUiThread(() -> onOptionSelectedListener.onSelected());
|
||||
|
||||
}
|
||||
catch(Exception e) {
|
||||
|
||||
activity.runOnUiThread(() -> Toasty.error(context, getString(R.string.genericError)));
|
||||
Log.e("onError", e.toString());
|
||||
|
||||
} finally {
|
||||
if(voidResponse.isPresent() && voidResponse.get().isSuccessful()) {
|
||||
onOptionSelectedListener.onSelected();
|
||||
} else {
|
||||
Toasty.error(context, getString(R.string.genericError));
|
||||
}
|
||||
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
thread.start();
|
||||
markRead.setOnClickListener(v1 ->
|
||||
RetrofitClient.getApiInterface(context)
|
||||
.markNotificationThreadAsRead(Authorization.get(context), notificationThread.getId(), "read")
|
||||
.enqueue((SimpleCallback<Void>) (call, voidResponse) -> {
|
||||
|
||||
});
|
||||
|
||||
markRead.setOnClickListener(v1 -> {
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
try {
|
||||
|
||||
notificationsActions.setNotificationStatus(notificationThread, NotificationsActions.NotificationStatus.READ);
|
||||
activity.runOnUiThread(() -> onOptionSelectedListener.onSelected());
|
||||
|
||||
}
|
||||
catch(Exception e) {
|
||||
|
||||
activity.runOnUiThread(() -> Toasty.error(context, getString(R.string.genericError)));
|
||||
Log.e("onError", e.toString());
|
||||
|
||||
} finally {
|
||||
if(voidResponse.isPresent() && voidResponse.get().isSuccessful()) {
|
||||
onOptionSelectedListener.onSelected();
|
||||
} else {
|
||||
Toasty.error(context, getString(R.string.genericError));
|
||||
}
|
||||
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
thread.start();
|
||||
markUnread.setOnClickListener(v13 ->
|
||||
RetrofitClient.getApiInterface(context)
|
||||
.markNotificationThreadAsRead(Authorization.get(context), notificationThread.getId(), "unread")
|
||||
.enqueue((SimpleCallback<Void>) (call, voidResponse) -> {
|
||||
|
||||
});
|
||||
|
||||
markUnread.setOnClickListener(v13 -> {
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
try {
|
||||
|
||||
notificationsActions.setNotificationStatus(notificationThread, NotificationsActions.NotificationStatus.UNREAD);
|
||||
activity.runOnUiThread(() -> onOptionSelectedListener.onSelected());
|
||||
|
||||
}
|
||||
catch(Exception e) {
|
||||
|
||||
activity.runOnUiThread(() -> Toasty.error(context, getString(R.string.genericError)));
|
||||
Log.e("onError", e.toString());
|
||||
|
||||
} finally {
|
||||
if(voidResponse.isPresent() && voidResponse.get().isSuccessful()) {
|
||||
onOptionSelectedListener.onSelected();
|
||||
} else {
|
||||
Toasty.error(context, getString(R.string.genericError));
|
||||
}
|
||||
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
thread.start();
|
||||
|
||||
});
|
||||
}));
|
||||
|
||||
return bottomSheetNotificationsBinding.getRoot();
|
||||
|
||||
|
|
|
@ -5,12 +5,10 @@ import android.content.ClipboardManager;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -18,8 +16,8 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
|||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.actions.IssueActions;
|
||||
import org.mian.gitnex.actions.PullRequestActions;
|
||||
import org.mian.gitnex.activities.DiffActivity;
|
||||
import org.mian.gitnex.activities.EditIssueActivity;
|
||||
import org.mian.gitnex.activities.FileDiffActivity;
|
||||
import org.mian.gitnex.activities.MergePullRequestActivity;
|
||||
import org.mian.gitnex.databinding.BottomSheetSingleIssueBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
|
@ -47,7 +45,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
|
|||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
|
||||
BottomSheetSingleIssueBinding bottomSheetSingleIssueBinding = BottomSheetSingleIssueBinding.inflate(inflater, container, false);
|
||||
BottomSheetSingleIssueBinding binding = BottomSheetSingleIssueBinding.inflate(inflater, container, false);
|
||||
|
||||
final Context ctx = getContext();
|
||||
final TinyDB tinyDB = TinyDB.getInstance(ctx);
|
||||
|
@ -57,38 +55,22 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
|
|||
boolean canPush = tinyDB.getBoolean("canPush");
|
||||
boolean archived = tinyDB.getBoolean("isArchived");
|
||||
|
||||
TextView editIssue = bottomSheetSingleIssueBinding.editIssue;
|
||||
TextView editLabels = bottomSheetSingleIssueBinding.editLabels;
|
||||
TextView closeIssue = bottomSheetSingleIssueBinding.closeIssue;
|
||||
TextView addRemoveAssignees = bottomSheetSingleIssueBinding.addRemoveAssignees;
|
||||
TextView copyIssueUrl = bottomSheetSingleIssueBinding.copyIssueUrl;
|
||||
TextView openFilesDiff = bottomSheetSingleIssueBinding.openFilesDiff;
|
||||
TextView updatePullRequest = bottomSheetSingleIssueBinding.updatePullRequest;
|
||||
TextView mergePullRequest = bottomSheetSingleIssueBinding.mergePullRequest;
|
||||
TextView deletePullRequestBranch = bottomSheetSingleIssueBinding.deletePrHeadBranch;
|
||||
TextView shareIssue = bottomSheetSingleIssueBinding.shareIssue;
|
||||
TextView subscribeIssue = bottomSheetSingleIssueBinding.subscribeIssue;
|
||||
TextView unsubscribeIssue = bottomSheetSingleIssueBinding.unsubscribeIssue;
|
||||
View closeReopenDivider = bottomSheetSingleIssueBinding.dividerCloseReopenIssue;
|
||||
|
||||
LinearLayout linearLayout = bottomSheetSingleIssueBinding.commentReactionButtons;
|
||||
|
||||
Bundle bundle1 = new Bundle();
|
||||
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
|
||||
bundle1.putString("repoOwner", parts[0]);
|
||||
bundle1.putString("repoName", parts[1]);
|
||||
bundle1.putInt("issueId", Integer.parseInt(tinyDB.getString("issueNumber")));
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
bundle.putString("repoOwner", parts[0]);
|
||||
bundle.putString("repoName", parts[1]);
|
||||
bundle.putInt("issueId", Integer.parseInt(tinyDB.getString("issueNumber")));
|
||||
|
||||
TextView loadReactions = new TextView(ctx);
|
||||
loadReactions.setText(Objects.requireNonNull(ctx).getString(R.string.genericWaitFor));
|
||||
loadReactions.setGravity(Gravity.CENTER);
|
||||
loadReactions.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 160));
|
||||
linearLayout.addView(loadReactions);
|
||||
loadReactions.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 80));
|
||||
binding.commentReactionButtons.addView(loadReactions);
|
||||
|
||||
ReactionSpinner reactionSpinner = new ReactionSpinner(ctx, bundle1);
|
||||
ReactionSpinner reactionSpinner = new ReactionSpinner(ctx, bundle);
|
||||
reactionSpinner.setOnInteractedListener(() -> {
|
||||
|
||||
tinyDB.putBoolean("singleIssueUpdate", true);
|
||||
|
@ -96,74 +78,72 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
|
|||
bmListener.onButtonClicked("onResume");
|
||||
dismiss();
|
||||
});
|
||||
|
||||
Handler handler = new Handler();
|
||||
handler.postDelayed(() -> {
|
||||
linearLayout.removeView(loadReactions);
|
||||
reactionSpinner.setOnLoadingFinishedListener(() -> {
|
||||
reactionSpinner.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 160));
|
||||
linearLayout.addView(reactionSpinner);
|
||||
}, 2500);
|
||||
binding.commentReactionButtons.removeView(loadReactions);
|
||||
binding.commentReactionButtons.addView(reactionSpinner);
|
||||
});
|
||||
|
||||
if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) {
|
||||
|
||||
editIssue.setText(R.string.editPrText);
|
||||
copyIssueUrl.setText(R.string.copyPrUrlText);
|
||||
shareIssue.setText(R.string.sharePr);
|
||||
binding.editIssue.setText(R.string.editPrText);
|
||||
binding.copyIssueUrl.setText(R.string.copyPrUrlText);
|
||||
binding.shareIssue.setText(R.string.sharePr);
|
||||
|
||||
boolean canPushPullSource = tinyDB.getBoolean("canPushPullSource");
|
||||
if(tinyDB.getBoolean("prMerged") || tinyDB.getString("repoPrState").equals("closed")) {
|
||||
updatePullRequest.setVisibility(View.GONE);
|
||||
mergePullRequest.setVisibility(View.GONE);
|
||||
binding.updatePullRequest.setVisibility(View.GONE);
|
||||
binding.mergePullRequest.setVisibility(View.GONE);
|
||||
if(canPushPullSource) {
|
||||
deletePullRequestBranch.setVisibility(View.VISIBLE);
|
||||
binding.deletePrHeadBranch.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
if(!canPush) {
|
||||
editIssue.setVisibility(View.GONE);
|
||||
binding.editIssue.setVisibility(View.GONE);
|
||||
}
|
||||
deletePullRequestBranch.setVisibility(View.GONE);
|
||||
binding.deletePrHeadBranch.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(canPushPullSource) {
|
||||
updatePullRequest.setVisibility(View.VISIBLE);
|
||||
binding.updatePullRequest.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
updatePullRequest.setVisibility(View.GONE);
|
||||
binding.updatePullRequest.setVisibility(View.GONE);
|
||||
}
|
||||
if(!userIsCreator && !canPush) {
|
||||
editIssue.setVisibility(View.GONE);
|
||||
binding.editIssue.setVisibility(View.GONE);
|
||||
}
|
||||
if(canPush && !tinyDB.getString("prMergeable").equals("false")) {
|
||||
mergePullRequest.setVisibility(View.VISIBLE);
|
||||
binding.mergePullRequest.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
mergePullRequest.setVisibility(View.GONE);
|
||||
binding.mergePullRequest.setVisibility(View.GONE);
|
||||
}
|
||||
deletePullRequestBranch.setVisibility(View.GONE);
|
||||
binding.deletePrHeadBranch.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.13.0")) {
|
||||
openFilesDiff.setVisibility(View.VISIBLE);
|
||||
binding.openFilesDiff.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else if(tinyDB.getString("repoType").equals("public")) {
|
||||
openFilesDiff.setVisibility(View.VISIBLE);
|
||||
binding.openFilesDiff.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
openFilesDiff.setVisibility(View.GONE);
|
||||
binding.openFilesDiff.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
if(!userIsCreator && !canPush) {
|
||||
editIssue.setVisibility(View.GONE);
|
||||
binding.editIssue.setVisibility(View.GONE);
|
||||
}
|
||||
updatePullRequest.setVisibility(View.GONE);
|
||||
mergePullRequest.setVisibility(View.GONE);
|
||||
deletePullRequestBranch.setVisibility(View.GONE);
|
||||
binding.updatePullRequest.setVisibility(View.GONE);
|
||||
binding.mergePullRequest.setVisibility(View.GONE);
|
||||
binding.deletePrHeadBranch.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
updatePullRequest.setOnClickListener(v -> {
|
||||
binding.updatePullRequest.setOnClickListener(v -> {
|
||||
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.16.0")) {
|
||||
AlertDialogs.selectPullUpdateStrategy(requireContext(), parts[0], parts[1], tinyDB.getString("issueNumber"));
|
||||
}
|
||||
|
@ -173,43 +153,40 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
|
|||
dismiss();
|
||||
});
|
||||
|
||||
mergePullRequest.setOnClickListener(v13 -> {
|
||||
|
||||
binding.mergePullRequest.setOnClickListener(v13 -> {
|
||||
startActivity(new Intent(ctx, MergePullRequestActivity.class));
|
||||
dismiss();
|
||||
});
|
||||
|
||||
deletePullRequestBranch.setOnClickListener(v -> {
|
||||
binding.openFilesDiff.setOnClickListener(v14 -> {
|
||||
startActivity(new Intent(ctx, DiffActivity.class));
|
||||
dismiss();
|
||||
});
|
||||
|
||||
binding.deletePrHeadBranch.setOnClickListener(v -> {
|
||||
|
||||
PullRequestActions.deleteHeadBranch(ctx, parts[0], parts[1], tinyDB.getString("prHeadBranch"), true);
|
||||
dismiss();
|
||||
});
|
||||
|
||||
openFilesDiff.setOnClickListener(v14 -> {
|
||||
|
||||
startActivity(new Intent(ctx, FileDiffActivity.class));
|
||||
dismiss();
|
||||
});
|
||||
|
||||
editIssue.setOnClickListener(v15 -> {
|
||||
|
||||
binding.editIssue.setOnClickListener(v15 -> {
|
||||
startActivity(new Intent(ctx, EditIssueActivity.class));
|
||||
dismiss();
|
||||
});
|
||||
|
||||
editLabels.setOnClickListener(v16 -> {
|
||||
|
||||
binding.editLabels.setOnClickListener(v16 -> {
|
||||
bmListener.onButtonClicked("showLabels");
|
||||
dismiss();
|
||||
});
|
||||
|
||||
addRemoveAssignees.setOnClickListener(v17 -> {
|
||||
|
||||
binding.addRemoveAssignees.setOnClickListener(v17 -> {
|
||||
bmListener.onButtonClicked("showAssignees");
|
||||
dismiss();
|
||||
});
|
||||
|
||||
shareIssue.setOnClickListener(v1 -> {
|
||||
binding.shareIssue.setOnClickListener(v1 -> {
|
||||
|
||||
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
|
||||
sharingIntent.setType("text/plain");
|
||||
|
@ -220,7 +197,7 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
|
|||
dismiss();
|
||||
});
|
||||
|
||||
copyIssueUrl.setOnClickListener(v12 -> {
|
||||
binding.copyIssueUrl.setOnClickListener(v12 -> {
|
||||
|
||||
// copy to clipboard
|
||||
ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
|
@ -235,13 +212,13 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
|
|||
|
||||
if(tinyDB.getString("issueState").equals("open")) { // close issue
|
||||
if(!userIsCreator && !canPush) {
|
||||
closeIssue.setVisibility(View.GONE);
|
||||
closeReopenDivider.setVisibility(View.GONE);
|
||||
binding.closeIssue.setVisibility(View.GONE);
|
||||
binding.dividerCloseReopenIssue.setVisibility(View.GONE);
|
||||
}
|
||||
else if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) {
|
||||
closeIssue.setText(R.string.closePr);
|
||||
binding.closeIssue.setText(R.string.closePr);
|
||||
}
|
||||
closeIssue.setOnClickListener(closeSingleIssue -> {
|
||||
binding.closeIssue.setOnClickListener(closeSingleIssue -> {
|
||||
IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "closed");
|
||||
dismiss();
|
||||
});
|
||||
|
@ -249,60 +226,60 @@ public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment {
|
|||
else if(tinyDB.getString("issueState").equals("closed")) {
|
||||
if(userIsCreator || canPush) {
|
||||
if(tinyDB.getString("issueType").equalsIgnoreCase("Pull")) {
|
||||
closeIssue.setText(R.string.reopenPr);
|
||||
binding.closeIssue.setText(R.string.reopenPr);
|
||||
}
|
||||
else {
|
||||
closeIssue.setText(R.string.reOpenIssue);
|
||||
binding.closeIssue.setText(R.string.reOpenIssue);
|
||||
}
|
||||
}
|
||||
else {
|
||||
closeIssue.setVisibility(View.GONE);
|
||||
closeReopenDivider.setVisibility(View.GONE);
|
||||
binding.closeIssue.setVisibility(View.GONE);
|
||||
binding.dividerCloseReopenIssue.setVisibility(View.GONE);
|
||||
}
|
||||
closeIssue.setOnClickListener(closeSingleIssue -> {
|
||||
binding.closeIssue.setOnClickListener(closeSingleIssue -> {
|
||||
IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "open");
|
||||
dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
subscribeIssue.setOnClickListener(subscribeToIssue -> {
|
||||
binding.subscribeIssue.setOnClickListener(subscribeToIssue -> {
|
||||
|
||||
IssueActions.subscribe(ctx);
|
||||
dismiss();
|
||||
});
|
||||
|
||||
unsubscribeIssue.setOnClickListener(unsubscribeToIssue -> {
|
||||
binding.unsubscribeIssue.setOnClickListener(unsubscribeToIssue -> {
|
||||
|
||||
IssueActions.unsubscribe(ctx);
|
||||
dismiss();
|
||||
});
|
||||
|
||||
if(new Version(tinyDB.getString("giteaVersion")).less("1.12.0")) {
|
||||
subscribeIssue.setVisibility(View.GONE);
|
||||
unsubscribeIssue.setVisibility(View.GONE);
|
||||
binding.subscribeIssue.setVisibility(View.GONE);
|
||||
binding.unsubscribeIssue.setVisibility(View.GONE);
|
||||
}
|
||||
else if(tinyDB.getBoolean("issueSubscribed")) {
|
||||
subscribeIssue.setVisibility(View.GONE);
|
||||
unsubscribeIssue.setVisibility(View.VISIBLE);
|
||||
binding.subscribeIssue.setVisibility(View.GONE);
|
||||
binding.unsubscribeIssue.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
subscribeIssue.setVisibility(View.VISIBLE);
|
||||
unsubscribeIssue.setVisibility(View.GONE);
|
||||
binding.subscribeIssue.setVisibility(View.VISIBLE);
|
||||
binding.unsubscribeIssue.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(archived) {
|
||||
subscribeIssue.setVisibility(View.GONE);
|
||||
unsubscribeIssue.setVisibility(View.GONE);
|
||||
editIssue.setVisibility(View.GONE);
|
||||
editLabels.setVisibility(View.GONE);
|
||||
closeIssue.setVisibility(View.GONE);
|
||||
closeReopenDivider.setVisibility(View.GONE);
|
||||
addRemoveAssignees.setVisibility(View.GONE);
|
||||
linearLayout.setVisibility(View.GONE);
|
||||
bottomSheetSingleIssueBinding.shareDivider.setVisibility(View.GONE);
|
||||
binding.subscribeIssue.setVisibility(View.GONE);
|
||||
binding.unsubscribeIssue.setVisibility(View.GONE);
|
||||
binding.editIssue.setVisibility(View.GONE);
|
||||
binding.editLabels.setVisibility(View.GONE);
|
||||
binding.closeIssue.setVisibility(View.GONE);
|
||||
binding.dividerCloseReopenIssue.setVisibility(View.GONE);
|
||||
binding.addRemoveAssignees.setVisibility(View.GONE);
|
||||
binding.commentReactionButtons.setVisibility(View.GONE);
|
||||
binding.shareDivider.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
return bottomSheetSingleIssueBinding.getRoot();
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
package org.mian.gitnex.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import org.gitnex.tea4j.models.FileDiffView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.DiffFilesAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.FragmentDiffFilesBinding;
|
||||
import org.mian.gitnex.helpers.AlertDialogs;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.ParseDiff;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import org.mian.gitnex.helpers.Version;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
|
||||
public class DiffFilesFragment extends Fragment {
|
||||
|
||||
private FragmentDiffFilesBinding binding;
|
||||
private Context ctx;
|
||||
private TinyDB tinyDB;
|
||||
|
||||
public DiffFilesFragment() {}
|
||||
|
||||
public static DiffFilesFragment newInstance() {
|
||||
return new DiffFilesFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
binding = FragmentDiffFilesBinding.inflate(inflater, container, false);
|
||||
ctx = requireContext();
|
||||
tinyDB = TinyDB.getInstance(ctx);
|
||||
|
||||
String repoFullName = tinyDB.getString("repoFullName");
|
||||
String[] parts = repoFullName.split("/");
|
||||
final String repoOwner = parts[0];
|
||||
final String repoName = parts[1];
|
||||
|
||||
String pullIndex = tinyDB.getString("issueNumber");
|
||||
|
||||
binding.progressBar.setVisibility(View.VISIBLE);
|
||||
binding.toolbarTitle.setText(R.string.processingText);
|
||||
binding.close.setOnClickListener(v -> requireActivity().finish());
|
||||
|
||||
binding.diffFiles.setOnItemClickListener((parent, view, position, id) -> requireActivity().getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, DiffFragment.newInstance((FileDiffView) parent.getItemAtPosition(position)))
|
||||
.commit());
|
||||
|
||||
getPullDiffFiles(repoOwner, repoName, pullIndex);
|
||||
|
||||
return binding.getRoot();
|
||||
|
||||
}
|
||||
|
||||
private void getPullDiffFiles(String owner, String repo, String pullIndex) {
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
|
||||
Call<ResponseBody> call = new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.13.0") ?
|
||||
RetrofitClient.getApiInterface(ctx).getPullDiffContent(Authorization.get(ctx), owner, repo, pullIndex) :
|
||||
RetrofitClient.getWebInterface(ctx).getPullDiffContent(Authorization.getWeb(ctx), owner, repo, pullIndex);
|
||||
|
||||
try {
|
||||
|
||||
Response<ResponseBody> response = call.execute();
|
||||
assert response.body() != null;
|
||||
|
||||
switch(response.code()) {
|
||||
|
||||
case 200:
|
||||
List<FileDiffView> fileDiffViews = ParseDiff.getFileDiffViewArray(response.body().string());
|
||||
|
||||
int filesCount = fileDiffViews.size();
|
||||
|
||||
String toolbarTitleText = (filesCount > 1) ?
|
||||
getResources().getString(R.string.fileDiffViewHeader, Integer.toString(filesCount)) :
|
||||
getResources().getString(R.string.fileDiffViewHeaderSingle, Integer.toString(filesCount));
|
||||
|
||||
DiffFilesAdapter adapter = new DiffFilesAdapter(ctx, fileDiffViews);
|
||||
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
binding.progressBar.setVisibility(View.GONE);
|
||||
binding.diffFiles.setAdapter(adapter);
|
||||
binding.toolbarTitle.setText(toolbarTitleText);
|
||||
});
|
||||
break;
|
||||
|
||||
case 401:
|
||||
requireActivity().runOnUiThread(() -> AlertDialogs.authorizationTokenRevokedDialog(ctx,
|
||||
getString(R.string.alertDialogTokenRevokedTitle),
|
||||
getString(R.string.alertDialogTokenRevokedMessage),
|
||||
getString(R.string.cancelButton),
|
||||
getString(R.string.cancelButton)));
|
||||
break;
|
||||
|
||||
case 403:
|
||||
requireActivity().runOnUiThread(() -> Toasty.error(ctx, ctx.getString(R.string.authorizeError)));
|
||||
break;
|
||||
|
||||
case 404:
|
||||
requireActivity().runOnUiThread(() -> Toasty.warning(ctx, ctx.getString(R.string.apiNotFound)));
|
||||
break;
|
||||
|
||||
default:
|
||||
requireActivity().runOnUiThread(() -> Toasty.error(ctx, getString(R.string.labelGeneralError)));
|
||||
|
||||
}
|
||||
} catch(IOException ignored) {}
|
||||
|
||||
});
|
||||
|
||||
thread.start();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package org.mian.gitnex.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import org.gitnex.tea4j.models.FileDiffView;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.DiffAdapter;
|
||||
import org.mian.gitnex.databinding.FragmentDiffBinding;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
|
||||
public class DiffFragment extends Fragment {
|
||||
|
||||
private FragmentDiffBinding binding;
|
||||
private Context ctx;
|
||||
|
||||
private FileDiffView fileDiffView;
|
||||
|
||||
public DiffFragment() {}
|
||||
|
||||
public void setFileDiffView(FileDiffView fileDiffView) {
|
||||
this.fileDiffView = fileDiffView;
|
||||
}
|
||||
|
||||
public static DiffFragment newInstance(FileDiffView fileDiffView) {
|
||||
|
||||
DiffFragment fragment = new DiffFragment();
|
||||
fragment.setFileDiffView(fileDiffView);
|
||||
return fragment;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
binding = FragmentDiffBinding.inflate(inflater, container, false);
|
||||
ctx = requireContext();
|
||||
|
||||
binding.close.setOnClickListener(v -> requireActivity().getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, DiffFilesFragment.newInstance())
|
||||
.commit());
|
||||
|
||||
binding.toolbarTitle.setText(fileDiffView.getFileName());
|
||||
binding.diff.setDivider(null);
|
||||
binding.diff.setAdapter(new DiffAdapter(ctx, getChildFragmentManager(), Arrays.asList(fileDiffView.toString().split("\\R"))));
|
||||
|
||||
return binding.getRoot();
|
||||
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ import android.view.ViewGroup;
|
|||
import android.view.inputmethod.EditorInfo;
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
|
@ -104,9 +105,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
|||
binding.recyclerView.setHasFixedSize(true);
|
||||
binding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
binding.recyclerView.setAdapter(filesAdapter);
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(binding.recyclerView.getContext(), DividerItemDecoration.VERTICAL);
|
||||
binding.recyclerView.addItemDecoration(dividerItemDecoration);
|
||||
binding.recyclerView.addItemDecoration(new DividerItemDecoration(binding.recyclerView.getContext(), DividerItemDecoration.VERTICAL));
|
||||
|
||||
binding.breadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref))));
|
||||
// noinspection unchecked
|
||||
|
@ -117,16 +116,11 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
|||
public void onNavigateBack(BreadcrumbItem item, int position) {
|
||||
|
||||
if(position == 0) {
|
||||
|
||||
path.clear();
|
||||
fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, ref);
|
||||
return;
|
||||
|
||||
} else {
|
||||
path.pop(path.size() - position);
|
||||
}
|
||||
|
||||
path.pop(path.size() - position);
|
||||
fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, path.toString(), ref);
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override public void onNavigateNewLocation(BreadcrumbItem newItem, int changedPosition) {}
|
||||
|
@ -151,34 +145,32 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
|||
}
|
||||
});
|
||||
|
||||
binding.pullToRefresh.setOnRefreshListener(() -> {
|
||||
refresh();
|
||||
binding.pullToRefresh.setRefreshing(false);
|
||||
});
|
||||
|
||||
((RepoDetailActivity) requireActivity()).setFragmentRefreshListenerFiles(repoBranch -> {
|
||||
|
||||
path.clear();
|
||||
ref = repoBranch;
|
||||
binding.breadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref))));
|
||||
fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, repoBranch);
|
||||
refresh();
|
||||
|
||||
});
|
||||
|
||||
|
||||
String dir = requireActivity().getIntent().getStringExtra("dir");
|
||||
if(dir != null) {
|
||||
fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, dir, ref);
|
||||
for(String segment: dir.split("/")) {
|
||||
binding.breadcrumbsView.addItem(new BreadcrumbItem(Collections.singletonList(segment)));
|
||||
path.add(segment);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, ref);
|
||||
}
|
||||
refresh();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -189,8 +181,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
|||
case "dir":
|
||||
path.add(file.getName());
|
||||
binding.breadcrumbsView.addItem(new BreadcrumbItem(Collections.singletonList(file.getName())));
|
||||
|
||||
fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, path.toString(), ref);
|
||||
refresh();
|
||||
break;
|
||||
|
||||
case "file":
|
||||
|
@ -302,6 +293,14 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
|||
}
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
if(path.size() > 0) {
|
||||
fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, path.toString(), ref);
|
||||
} else {
|
||||
fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, ref);
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchDataAsync(String instanceToken, String owner, String repo, String ref) {
|
||||
|
||||
binding.recyclerView.setVisibility(View.GONE);
|
||||
|
@ -365,15 +364,17 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
|||
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
||||
|
||||
menu.clear();
|
||||
|
||||
inflater.inflate(R.menu.search_menu, menu);
|
||||
inflater.inflate(R.menu.files_switch_branches_menu, menu);
|
||||
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
|
||||
MenuItem searchItem = menu.findItem(R.id.action_search);
|
||||
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
|
||||
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
|
||||
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
|
||||
SearchView searchView = (SearchView) searchItem.getActionView();
|
||||
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
|
@ -401,7 +402,6 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
|
|||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
|
||||
super.onDetach();
|
||||
mListener = null;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import android.content.Intent;
|
|||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -22,24 +21,20 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.gitnex.tea4j.models.NotificationThread;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.actions.NotificationsActions;
|
||||
import org.mian.gitnex.activities.IssueDetailActivity;
|
||||
import org.mian.gitnex.activities.RepoDetailActivity;
|
||||
import org.mian.gitnex.adapters.NotificationsAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.FragmentNotificationsBinding;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.SnackBar;
|
||||
import org.mian.gitnex.helpers.SimpleCallback;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author opyale
|
||||
|
@ -49,17 +44,16 @@ import retrofit2.Response;
|
|||
public class NotificationsFragment extends Fragment implements NotificationsAdapter.OnNotificationClickedListener, NotificationsAdapter.OnMoreClickedListener, BottomSheetNotificationsFragment.OnOptionSelectedListener {
|
||||
|
||||
private FragmentNotificationsBinding viewBinding;
|
||||
private List<NotificationThread> notificationThreads;
|
||||
private final List<NotificationThread> notificationThreads = new ArrayList<>();
|
||||
private NotificationsAdapter notificationsAdapter;
|
||||
private NotificationsActions notificationsActions;
|
||||
|
||||
private Activity activity;
|
||||
private Context context;
|
||||
private TinyDB tinyDB;
|
||||
private Menu menu;
|
||||
|
||||
private int resultLimit;
|
||||
private int pageSize;
|
||||
private int pageCurrentIndex = 1;
|
||||
private int pageResultLimit;
|
||||
private String currentFilterMode = "unread";
|
||||
private final String TAG = Constants.tagNotifications;
|
||||
private String instanceToken;
|
||||
|
@ -81,14 +75,11 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
|
|||
context = getContext();
|
||||
tinyDB = TinyDB.getInstance(context);
|
||||
|
||||
String loginUid = tinyDB.getString("loginUid");
|
||||
instanceToken = "token " + tinyDB.getString(loginUid + "-token");
|
||||
instanceToken = Authorization.get(context);
|
||||
|
||||
resultLimit = Constants.getCurrentResultLimit(context);
|
||||
pageResultLimit = Constants.getCurrentResultLimit(context);
|
||||
tinyDB.putString("notificationsFilterState", currentFilterMode);
|
||||
|
||||
notificationThreads = new ArrayList<>();
|
||||
notificationsActions = new NotificationsActions(context);
|
||||
notificationsAdapter = new NotificationsAdapter(context, notificationThreads, this, this);
|
||||
|
||||
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
|
||||
|
@ -100,18 +91,10 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
|
|||
viewBinding.notifications.setAdapter(notificationsAdapter);
|
||||
viewBinding.notifications.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
viewBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
viewBinding.pullToRefresh.setRefreshing(false);
|
||||
loadInitial(resultLimit);
|
||||
notificationsAdapter.notifyDataChanged();
|
||||
}, 200));
|
||||
|
||||
notificationsAdapter.setLoadMoreListener(() -> viewBinding.notifications.post(() -> {
|
||||
if(notificationThreads.size() == resultLimit || pageSize == resultLimit) {
|
||||
int page = (notificationThreads.size() + resultLimit) / resultLimit;
|
||||
loadMore(resultLimit, page);
|
||||
}
|
||||
}));
|
||||
notificationsAdapter.setLoadMoreListener(() -> {
|
||||
pageCurrentIndex++;
|
||||
loadNotifications(true);
|
||||
});
|
||||
|
||||
viewBinding.notifications.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
|
||||
|
@ -133,141 +116,78 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
|
|||
}
|
||||
});
|
||||
|
||||
viewBinding.markAllAsRead.setOnClickListener(v1 -> {
|
||||
viewBinding.markAllAsRead.setOnClickListener(v1 ->
|
||||
RetrofitClient.getApiInterface(context)
|
||||
.markNotificationThreadsAsRead(Authorization.get(context), AppUtil.getTimestampFromDate(context, new Date()), true, new String[]{"unread", "pinned"}, "read")
|
||||
.enqueue((SimpleCallback<Void>) (call, voidResponse) -> {
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
try {
|
||||
if(notificationsActions.setAllNotificationsRead(new Date())) {
|
||||
activity.runOnUiThread(() -> {
|
||||
Toasty.success(context, getString(R.string.markedNotificationsAsRead));
|
||||
loadInitial(resultLimit);
|
||||
});
|
||||
if(voidResponse.isPresent() && voidResponse.get().isSuccessful()) {
|
||||
Toasty.success(context, getString(R.string.markedNotificationsAsRead));
|
||||
pageCurrentIndex = 1;
|
||||
loadNotifications(false);
|
||||
} else {
|
||||
activity.runOnUiThread(() -> Toasty.error(context, getString(R.string.genericError)));
|
||||
}
|
||||
}
|
||||
catch(IOException e) {
|
||||
activity.runOnUiThread(() -> Toasty.error(context, getString(R.string.genericError)));
|
||||
Log.e("onError", e.toString());
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
});
|
||||
}));
|
||||
|
||||
viewBinding.pullToRefresh.setOnRefreshListener(() -> {
|
||||
loadInitial(resultLimit);
|
||||
viewBinding.pullToRefresh.setRefreshing(false);
|
||||
pageCurrentIndex = 1;
|
||||
loadNotifications(false);
|
||||
});
|
||||
|
||||
loadInitial(resultLimit);
|
||||
loadNotifications(true);
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
private void loadInitial(int resultLimit) {
|
||||
private void loadNotifications(boolean append) {
|
||||
|
||||
notificationThreads.clear();
|
||||
notificationsAdapter.notifyDataChanged();
|
||||
viewBinding.noDataNotifications.setVisibility(View.GONE);
|
||||
viewBinding.progressBar.setVisibility(View.VISIBLE);
|
||||
notificationThreads.clear();
|
||||
|
||||
String[] filter = tinyDB.getString("notificationsFilterState").equals("read") ?
|
||||
new String[]{"pinned", "read"} :
|
||||
new String[]{"pinned", "unread"};
|
||||
viewBinding.pullToRefresh.setRefreshing(false);
|
||||
|
||||
Call<List<NotificationThread>> call = RetrofitClient
|
||||
RetrofitClient
|
||||
.getApiInterface(context)
|
||||
.getNotificationThreads(instanceToken, false, filter,
|
||||
Constants.defaultOldestTimestamp, "",
|
||||
1, resultLimit);
|
||||
call.enqueue(new Callback<List<NotificationThread>>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<NotificationThread>> call, @NonNull Response<List<NotificationThread>> response) {
|
||||
if(response.isSuccessful()) {
|
||||
if(response.body() != null && response.body().size() > 0) {
|
||||
notificationThreads.addAll(response.body());
|
||||
notificationsAdapter.notifyDataChanged();
|
||||
viewBinding.noDataNotifications.setVisibility(View.GONE);
|
||||
.getNotificationThreads(instanceToken, false, filter, Constants.defaultOldestTimestamp, "", pageCurrentIndex, pageResultLimit)
|
||||
.enqueue((SimpleCallback<List<NotificationThread>>) (call1, listResponse) -> {
|
||||
|
||||
if(listResponse.isPresent() && listResponse.get().isSuccessful() && listResponse.get().body() != null) {
|
||||
System.out.println(listResponse.get().body());
|
||||
if(!append) {
|
||||
notificationThreads.clear();
|
||||
}
|
||||
|
||||
if(listResponse.get().body().size() > 0) {
|
||||
notificationThreads.addAll(listResponse.get().body());
|
||||
notificationsAdapter.notifyDataSetChanged();
|
||||
}
|
||||
else {
|
||||
notificationsAdapter.notifyDataChanged();
|
||||
viewBinding.noDataNotifications.setVisibility(View.VISIBLE);
|
||||
}
|
||||
viewBinding.progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
else if(response.code() == 404) {
|
||||
viewBinding.noDataNotifications.setVisibility(View.VISIBLE);
|
||||
viewBinding.progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
notificationsAdapter.notifyDataChanged();
|
||||
Log.e(TAG, String.valueOf(response.code()));
|
||||
}
|
||||
onCleanup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<NotificationThread>> call, @NonNull Throwable t) {
|
||||
Log.e(TAG, t.toString());
|
||||
onCleanup();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadMore(int resultLimit, int page) {
|
||||
|
||||
String[] filter = tinyDB.getString("notificationsFilterState").equals("read") ?
|
||||
new String[]{"pinned", "read"} :
|
||||
new String[]{"pinned", "unread"};
|
||||
|
||||
viewBinding.progressBar.setVisibility(View.VISIBLE);
|
||||
Call<List<NotificationThread>> call = RetrofitClient.getApiInterface(context)
|
||||
.getNotificationThreads(instanceToken, false, filter,
|
||||
Constants.defaultOldestTimestamp, "",
|
||||
page, resultLimit);
|
||||
call.enqueue(new Callback<List<NotificationThread>>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<NotificationThread>> call, @NonNull Response<List<NotificationThread>> response) {
|
||||
if(response.code() == 200) {
|
||||
assert response.body() != null;
|
||||
List<NotificationThread> result = response.body();
|
||||
|
||||
if(result.size() > 0) {
|
||||
pageSize = result.size();
|
||||
notificationThreads.addAll(result);
|
||||
}
|
||||
else {
|
||||
SnackBar.info(context, viewBinding.getRoot(), getString(R.string.noMoreData));
|
||||
notificationsAdapter.setMoreDataAvailable(false);
|
||||
}
|
||||
notificationsAdapter.notifyDataChanged();
|
||||
viewBinding.progressBar.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
AppUtil.setMultiVisibility(View.GONE, viewBinding.progressBar);
|
||||
|
||||
if(notificationThreads.isEmpty()) {
|
||||
viewBinding.noDataNotifications.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
Log.e(TAG, String.valueOf(response.code()));
|
||||
viewBinding.noDataNotifications.setVisibility(View.GONE);
|
||||
}
|
||||
onCleanup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<NotificationThread>> call, @NonNull Throwable t) {
|
||||
Log.e(TAG, t.toString());
|
||||
onCleanup();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onCleanup() {
|
||||
|
||||
AppUtil.setMultiVisibility(View.GONE, viewBinding.progressBar, viewBinding.progressBar);
|
||||
viewBinding.pullToRefresh.setRefreshing(false);
|
||||
|
||||
if(currentFilterMode.equalsIgnoreCase("unread")) {
|
||||
|
||||
if(notificationThreads.isEmpty()) {
|
||||
viewBinding.noDataNotifications.setVisibility(View.VISIBLE);
|
||||
viewBinding.markAllAsRead.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
viewBinding.markAllAsRead.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
if(currentFilterMode.equalsIgnoreCase("unread")) {
|
||||
if(notificationThreads.isEmpty()) {
|
||||
viewBinding.markAllAsRead.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
viewBinding.markAllAsRead.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void changeFilterMode() {
|
||||
|
@ -280,8 +200,7 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
|
|||
|
||||
if(currentFilterMode.equalsIgnoreCase("read")) {
|
||||
viewBinding.markAllAsRead.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
viewBinding.markAllAsRead.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
@ -291,7 +210,6 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
|
|||
|
||||
this.menu = menu;
|
||||
inflater.inflate(R.menu.filter_menu_notifications, menu);
|
||||
currentFilterMode = tinyDB.getString("notificationsFilterState");
|
||||
changeFilterMode();
|
||||
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
|
@ -308,7 +226,9 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
|
|||
|
||||
currentFilterMode = tinyDB.getString("notificationsFilterState");
|
||||
changeFilterMode();
|
||||
loadInitial(resultLimit);
|
||||
pageCurrentIndex = 1;
|
||||
loadNotifications(false);
|
||||
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
@ -318,16 +238,14 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
|
|||
@Override
|
||||
public void onNotificationClicked(NotificationThread notificationThread) {
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
try {
|
||||
if(notificationThread.isUnread()) {
|
||||
notificationsActions.setNotificationStatus(notificationThread, NotificationsActions.NotificationStatus.READ);
|
||||
activity.runOnUiThread(() -> loadInitial(resultLimit));
|
||||
if(notificationThread.isUnread() && !notificationThread.isPinned()) {
|
||||
RetrofitClient.getApiInterface(context).markNotificationThreadAsRead(Authorization.get(context), notificationThread.getId(), "read").enqueue((SimpleCallback<Void>) (call, voidResponse) -> {
|
||||
if(voidResponse.isPresent() && voidResponse.get().isSuccessful()) {
|
||||
pageCurrentIndex = 1;
|
||||
loadNotifications(false);
|
||||
}
|
||||
} catch(IOException ignored) {}
|
||||
});
|
||||
|
||||
thread.start();
|
||||
});
|
||||
}
|
||||
|
||||
if(StringUtils.containsAny(notificationThread.getSubject().getType().toLowerCase(), "pull", "issue")) {
|
||||
|
||||
|
@ -356,6 +274,7 @@ public class NotificationsFragment extends Fragment implements NotificationsAdap
|
|||
|
||||
@Override
|
||||
public void onSelected() {
|
||||
loadInitial(resultLimit);
|
||||
pageCurrentIndex = 1;
|
||||
loadNotifications(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package org.mian.gitnex.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import org.gitnex.tea4j.models.Teams;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.adapters.UserGridAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.databinding.FragmentOrganizationTeamInfoMembersBinding;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
|
||||
public class OrganizationTeamInfoMembersFragment extends Fragment {
|
||||
|
||||
private Context ctx;
|
||||
|
||||
private FragmentOrganizationTeamInfoMembersBinding binding;
|
||||
private Teams team;
|
||||
|
||||
private UserGridAdapter adapter;
|
||||
private final List<UserInfo> teamUserInfo = new ArrayList<>();
|
||||
|
||||
public OrganizationTeamInfoMembersFragment() {}
|
||||
|
||||
public static OrganizationTeamInfoMembersFragment newInstance(Teams team) {
|
||||
OrganizationTeamInfoMembersFragment fragment = new OrganizationTeamInfoMembersFragment();
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable("team", team);
|
||||
fragment.setArguments(bundle);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
binding = FragmentOrganizationTeamInfoMembersBinding.inflate(inflater, container, false);
|
||||
ctx = getContext();
|
||||
|
||||
team = (Teams) requireArguments().getSerializable("team");
|
||||
|
||||
adapter = new UserGridAdapter(ctx, teamUserInfo);
|
||||
binding.members.setAdapter(adapter);
|
||||
fetchMembersAsync();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void fetchMembersAsync() {
|
||||
|
||||
Call<List<UserInfo>> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.getTeamMembersByOrg(Authorization.get(ctx), team.getId());
|
||||
|
||||
binding.progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
call.enqueue(new Callback<List<UserInfo>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<UserInfo>> call, @NonNull Response<List<UserInfo>> response) {
|
||||
if(response.isSuccessful() && response.body() != null && response.body().size() > 0) {
|
||||
teamUserInfo.clear();
|
||||
teamUserInfo.addAll(response.body());
|
||||
|
||||
adapter.notifyDataSetChanged();
|
||||
|
||||
binding.noDataMembers.setVisibility(View.GONE);
|
||||
binding.members.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.members.setVisibility(View.GONE);
|
||||
binding.noDataMembers.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
binding.progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<UserInfo>> call, @NonNull Throwable t) {
|
||||
Log.i("onFailure", t.toString());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package org.mian.gitnex.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import org.gitnex.tea4j.models.Teams;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.databinding.FragmentOrganizationTeamInfoPermissionsBinding;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
|
||||
public class OrganizationTeamInfoPermissionsFragment extends Fragment {
|
||||
|
||||
private FragmentOrganizationTeamInfoPermissionsBinding binding;
|
||||
private Teams team;
|
||||
|
||||
public OrganizationTeamInfoPermissionsFragment() {}
|
||||
|
||||
public static OrganizationTeamInfoPermissionsFragment newInstance(Teams team) {
|
||||
OrganizationTeamInfoPermissionsFragment fragment = new OrganizationTeamInfoPermissionsFragment();
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable("team", team);
|
||||
fragment.setArguments(bundle);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
binding = FragmentOrganizationTeamInfoPermissionsBinding.inflate(inflater, container, false);
|
||||
|
||||
team = (Teams) requireArguments().getSerializable("team");
|
||||
|
||||
StringBuilder permissions = new StringBuilder();
|
||||
|
||||
// Future proofing in case of gitea becoming able to assign multiple permissions per team
|
||||
for(String permission : Collections.singletonList(team.getPermission())) {
|
||||
|
||||
switch(permission) {
|
||||
case "none":
|
||||
permissions.append(getString(R.string.teamPermissionNone)).append("\n");
|
||||
break;
|
||||
case "read":
|
||||
permissions.append(getString(R.string.teamPermissionRead)).append("\n");
|
||||
break;
|
||||
case "write":
|
||||
permissions.append(getString(R.string.teamPermissionWrite)).append("\n");
|
||||
break;
|
||||
case "admin":
|
||||
permissions.append(getString(R.string.teamPermissionAdmin)).append("\n");
|
||||
break;
|
||||
case "owner":
|
||||
permissions.append(getString(R.string.teamPermissionOwner)).append("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
binding.permissions.setText(permissions.toString());
|
||||
binding.progressBar.setVisibility(View.GONE);
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@ import org.apache.commons.io.FileUtils;
|
|||
import org.gitnex.tea4j.models.UserRepositories;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.activities.RepoDetailActivity;
|
||||
import org.mian.gitnex.activities.RepoForksActivity;
|
||||
import org.mian.gitnex.activities.RepoStargazersActivity;
|
||||
import org.mian.gitnex.activities.RepoWatchersActivity;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
|
@ -111,6 +112,13 @@ public class RepoInfoFragment extends Fragment {
|
|||
ctx.startActivity(intent);
|
||||
});
|
||||
|
||||
binding.repoMetaForksFrame.setOnClickListener(v -> {
|
||||
|
||||
Intent intent = new Intent(ctx, RepoForksActivity.class);
|
||||
intent.putExtra("repoFullNameForForks", repoOwner + "/" + repoName);
|
||||
ctx.startActivity(intent);
|
||||
});
|
||||
|
||||
binding.repoMetaPullRequestsFrame.setOnClickListener(metaPR -> RepoDetailActivity.mViewPager.setCurrentItem(3));
|
||||
|
||||
return binding.getRoot();
|
||||
|
|
|
@ -14,9 +14,7 @@ import android.view.inputmethod.EditorInfo;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
@ -30,7 +28,6 @@ import org.mian.gitnex.databinding.FragmentTeamsByOrgBinding;
|
|||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.viewmodels.TeamsByOrgViewModel;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
|
@ -117,21 +114,17 @@ public class TeamsByOrgFragment extends Fragment {
|
|||
|
||||
TeamsByOrgViewModel teamModel = new ViewModelProvider(this).get(TeamsByOrgViewModel.class);
|
||||
|
||||
teamModel.getTeamsByOrg(instanceToken, owner, getContext(), noDataTeams, mProgressBar).observe(getViewLifecycleOwner(), new Observer<List<Teams>>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable List<Teams> orgTeamsListMain) {
|
||||
adapter = new TeamsByOrgAdapter(getContext(), orgTeamsListMain, permissions);
|
||||
if(adapter.getItemCount() > 0) {
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
noDataTeams.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
adapter.notifyDataSetChanged();
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
noDataTeams.setVisibility(View.VISIBLE);
|
||||
}
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
teamModel.getTeamsByOrg(instanceToken, owner, getContext(), noDataTeams, mProgressBar).observe(getViewLifecycleOwner(), orgTeamsListMain -> {
|
||||
adapter = new TeamsByOrgAdapter(getContext(), orgTeamsListMain, permissions);
|
||||
if(adapter.getItemCount() > 0) {
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
noDataTeams.setVisibility(View.GONE);
|
||||
} else {
|
||||
adapter.notifyDataSetChanged();
|
||||
mRecyclerView.setAdapter(adapter);
|
||||
noDataTeams.setVisibility(View.VISIBLE);
|
||||
}
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -302,7 +302,7 @@ public class AppUtil {
|
|||
|
||||
long lines = 0;
|
||||
|
||||
Pattern pattern = Pattern.compile("(\r\n|\r|\n)");
|
||||
Pattern pattern = Pattern.compile("(\r\n|\n)");
|
||||
Matcher matcher = pattern.matcher(s);
|
||||
|
||||
while(matcher.find())
|
||||
|
|
|
@ -16,7 +16,7 @@ public class ColorInverter {
|
|||
@ColorInt
|
||||
public int getContrastColor(@ColorInt int color) {
|
||||
|
||||
double a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;
|
||||
double a = 1 - (0.2126 * Color.red(color) + 0.7152 * Color.green(color) + 0.0722 * Color.blue(color)) / 255;
|
||||
|
||||
int d = (a < 0.30) ?
|
||||
30 : // almost black
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.mian.gitnex.clients.PicassoService;
|
|||
import org.mian.gitnex.core.MainGrammarLocator;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -70,14 +70,13 @@ import stormpot.Timeout;
|
|||
|
||||
public class Markdown {
|
||||
|
||||
private static final int MAX_POOL_SIZE = 45;
|
||||
private static final int MAX_THREAD_KEEP_ALIVE_SECONDS = 120;
|
||||
private static final int MAX_CLAIM_TIMEOUT_SECONDS = 120;
|
||||
private static final int MAX_OBJECT_POOL_SIZE = 45;
|
||||
private static final int MAX_THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
private static final Timeout timeout = new Timeout(MAX_CLAIM_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
private static final Timeout OBJECT_POOL_CLAIM_TIMEOUT = new Timeout(240, TimeUnit.SECONDS);
|
||||
|
||||
private static final ExecutorService executorService = new ThreadPoolExecutor(MAX_POOL_SIZE / 2, MAX_POOL_SIZE, MAX_THREAD_KEEP_ALIVE_SECONDS,
|
||||
TimeUnit.SECONDS, new SynchronousQueue<>());
|
||||
private static final ExecutorService executorService =
|
||||
new ThreadPoolExecutor(MAX_THREAD_POOL_SIZE, MAX_THREAD_POOL_SIZE, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
|
||||
|
||||
private static final Pool<Renderer> rendererPool;
|
||||
private static final Pool<RecyclerViewRenderer> rvRendererPool;
|
||||
|
@ -88,19 +87,15 @@ public class Markdown {
|
|||
|
||||
config.setBackgroundExpirationEnabled(true);
|
||||
config.setPreciseLeakDetectionEnabled(true);
|
||||
config.setSize(MAX_POOL_SIZE);
|
||||
config.setSize(MAX_OBJECT_POOL_SIZE);
|
||||
config.setAllocator(new Allocator<Renderer>() {
|
||||
|
||||
@Override
|
||||
public Renderer allocate(Slot slot) {
|
||||
|
||||
return new Renderer(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deallocate(Renderer poolable) {
|
||||
|
||||
}
|
||||
@Override public void deallocate(Renderer poolable) {}
|
||||
|
||||
});
|
||||
|
||||
|
@ -110,7 +105,7 @@ public class Markdown {
|
|||
|
||||
configRv.setBackgroundExpirationEnabled(true);
|
||||
configRv.setPreciseLeakDetectionEnabled(true);
|
||||
configRv.setSize(MAX_POOL_SIZE);
|
||||
configRv.setSize(MAX_OBJECT_POOL_SIZE);
|
||||
configRv.setAllocator(new Allocator<RecyclerViewRenderer>() {
|
||||
|
||||
@Override
|
||||
|
@ -133,7 +128,7 @@ public class Markdown {
|
|||
public static void render(Context context, String markdown, TextView textView) {
|
||||
|
||||
try {
|
||||
Renderer renderer = rendererPool.claim(timeout);
|
||||
Renderer renderer = rendererPool.claim(OBJECT_POOL_CLAIM_TIMEOUT);
|
||||
|
||||
if(renderer != null) {
|
||||
renderer.setParameters(context, markdown, textView);
|
||||
|
@ -147,7 +142,7 @@ public class Markdown {
|
|||
public static void render(Context context, String markdown, RecyclerView recyclerView) {
|
||||
|
||||
try {
|
||||
RecyclerViewRenderer renderer = rvRendererPool.claim(timeout);
|
||||
RecyclerViewRenderer renderer = rvRendererPool.claim(OBJECT_POOL_CLAIM_TIMEOUT);
|
||||
|
||||
if(renderer != null) {
|
||||
renderer.setParameters(context, markdown, recyclerView);
|
||||
|
@ -234,7 +229,6 @@ public class Markdown {
|
|||
}
|
||||
|
||||
public void setParameters(Context context, String markdown, TextView textView) {
|
||||
|
||||
this.context = context;
|
||||
this.markdown = markdown;
|
||||
this.textView = textView;
|
||||
|
@ -242,7 +236,6 @@ public class Markdown {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
Objects.requireNonNull(context);
|
||||
Objects.requireNonNull(markdown);
|
||||
Objects.requireNonNull(textView);
|
||||
|
@ -257,18 +250,15 @@ public class Markdown {
|
|||
localReference.post(() -> localReference.setText(processedMarkdown));
|
||||
|
||||
release();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
|
||||
context = null;
|
||||
markdown = null;
|
||||
textView = null;
|
||||
|
||||
slot.release(this);
|
||||
|
||||
}
|
||||
|
||||
public void expire() {
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.mian.gitnex.helpers;
|
|||
|
||||
import org.gitnex.tea4j.models.FileDiffView;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -53,10 +54,11 @@ public class ParseDiff {
|
|||
|
||||
public static List<FileDiffView> getFileDiffViewArray(String raw) {
|
||||
|
||||
List<FileDiffView> fileContentsArray = new ArrayList<>();
|
||||
|
||||
String[] lines = raw.split("(^|\\n)diff --git a/");
|
||||
List<FileDiffView> fileContentsArray;
|
||||
|
||||
if(lines.length > 1) {
|
||||
fileContentsArray = new ArrayList<>(lines.length);
|
||||
|
||||
// for each file in diff
|
||||
for(int i = 1; i < lines.length; i++) {
|
||||
|
@ -137,6 +139,8 @@ public class ParseDiff {
|
|||
fileContentsArray.add(new FileDiffView(lines2[1], lines2[2].split("\\n")[0], "rename", "rename", null));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fileContentsArray = Collections.emptyList();
|
||||
}
|
||||
|
||||
return fileContentsArray;
|
||||
|
|
|
@ -57,7 +57,7 @@ public class RecyclerViewEmptySupport extends RecyclerView {
|
|||
@Override
|
||||
public void setAdapter(Adapter adapter) {
|
||||
|
||||
final Adapter oldAdapter = getAdapter();
|
||||
final Adapter<?> oldAdapter = getAdapter();
|
||||
if (oldAdapter != null) {
|
||||
oldAdapter.unregisterAdapterDataObserver(observer);
|
||||
}
|
||||
|
@ -74,4 +74,4 @@ public class RecyclerViewEmptySupport extends RecyclerView {
|
|||
this.emptyView = emptyView;
|
||||
checkIfEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package org.mian.gitnex.helpers;
|
||||
|
||||
import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
import java.io.File;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
|
||||
public interface SimpleCallback<T> extends Callback<T> {
|
||||
|
||||
void onFinished(@NonNull Call<T> call, @NonNull Optional<Response<T>> optionalResponse);
|
||||
|
||||
default void onResponse(@NonNull Call<T> call, @NonNull Response<T> response) {
|
||||
onFinished(call, Optional.of(response));
|
||||
}
|
||||
|
||||
default void onFailure(@NonNull Call<T> call, @NonNull Throwable throwable) {
|
||||
onFinished(call, Optional.empty());
|
||||
|
||||
Log.e(call.request().url()
|
||||
.pathSegments()
|
||||
.stream()
|
||||
.collect(Collectors.joining(File.pathSeparator)), throwable.toString());
|
||||
}
|
||||
|
||||
}
|
|
@ -22,44 +22,41 @@ public class TimeHelper {
|
|||
String part1 = parts[0] + "Z";
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
|
||||
Date createdTime = null;
|
||||
|
||||
try {
|
||||
createdTime = formatter.parse(part1);
|
||||
}
|
||||
catch(ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch(ParseException ignored) {}
|
||||
|
||||
DateFormat format = DateFormat.getDateTimeInstance();
|
||||
assert createdTime != null;
|
||||
|
||||
return format.format(createdTime);
|
||||
|
||||
}
|
||||
|
||||
public static String formatTime(Date date, Locale locale, String timeFormat, Context context) {
|
||||
|
||||
if(date == null) {
|
||||
return "";
|
||||
}
|
||||
if(date != null) {
|
||||
switch(timeFormat) {
|
||||
|
||||
switch(timeFormat) {
|
||||
case "pretty": {
|
||||
PrettyTime prettyTime = new PrettyTime(locale);
|
||||
return prettyTime.format(date);
|
||||
}
|
||||
case "normal": {
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
return formatter.format(date);
|
||||
}
|
||||
case "normal1": {
|
||||
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
return formatter.format(date);
|
||||
}
|
||||
|
||||
case "pretty": {
|
||||
PrettyTime prettyTime = new PrettyTime(locale);
|
||||
return prettyTime.format(date);
|
||||
}
|
||||
|
||||
case "normal": {
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
return formatter.format(date);
|
||||
}
|
||||
|
||||
case "normal1": {
|
||||
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", locale);
|
||||
return formatter.format(date);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
public static String customDateFormatForToastDateFormat(Date customDate) {
|
||||
|
@ -84,8 +81,7 @@ public class TimeHelper {
|
|||
if(to.before(from)) {
|
||||
if(cal.after(to)) {
|
||||
to.add(Calendar.DATE, 1);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
from.add(Calendar.DATE, -1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
package org.mian.gitnex.viewmodels;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class TeamMembersByOrgViewModel extends ViewModel {
|
||||
|
||||
private static MutableLiveData<List<UserInfo>> teamMembersList;
|
||||
|
||||
public LiveData<List<UserInfo>> getMembersByOrgList(String token, int teamId, Context ctx, TextView noDataMembers, ProgressBar progressBar) {
|
||||
|
||||
teamMembersList = new MutableLiveData<>();
|
||||
loadMembersByOrgList(token, teamId, ctx, noDataMembers, progressBar);
|
||||
|
||||
return teamMembersList;
|
||||
}
|
||||
|
||||
private static void loadMembersByOrgList(String token, int teamId, Context ctx, TextView noDataMembers, ProgressBar progressBar) {
|
||||
|
||||
Call<List<UserInfo>> call = RetrofitClient
|
||||
.getApiInterface(ctx)
|
||||
.getTeamMembersByOrg(token, teamId);
|
||||
|
||||
call.enqueue(new Callback<List<UserInfo>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<UserInfo>> call, @NonNull Response<List<UserInfo>> response) {
|
||||
|
||||
if (response.isSuccessful()) {
|
||||
teamMembersList.postValue(response.body());
|
||||
} else {
|
||||
Log.i("onResponse", String.valueOf(response.code()));
|
||||
progressBar.setVisibility(View.GONE);
|
||||
if(response.code() == 403) {
|
||||
noDataMembers.setText(R.string.authorizeError);
|
||||
} else {
|
||||
noDataMembers.setText(R.string.genericError);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<UserInfo>> call, @NonNull Throwable t) {
|
||||
Log.i("onFailure", t.toString());
|
||||
progressBar.setVisibility(View.GONE);
|
||||
noDataMembers.setText(R.string.genericError);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package org.mian.gitnex.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
/**
|
||||
* Author opyale
|
||||
*/
|
||||
|
||||
public class DiffTextView extends androidx.appcompat.widget.AppCompatTextView {
|
||||
|
||||
private int initialBackgroundColor;
|
||||
private int currentBackgroundColor;
|
||||
private long position;
|
||||
|
||||
public DiffTextView(Context context) {
|
||||
|
||||
super(context);
|
||||
}
|
||||
|
||||
public DiffTextView(Context context, AttributeSet attrs) {
|
||||
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public DiffTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackgroundColor(int color) {
|
||||
|
||||
currentBackgroundColor = color;
|
||||
super.setBackgroundColor(color);
|
||||
}
|
||||
|
||||
public void setInitialBackgroundColor(int initialBackgroundColor) {
|
||||
|
||||
setBackgroundColor(initialBackgroundColor);
|
||||
this.initialBackgroundColor = initialBackgroundColor;
|
||||
}
|
||||
|
||||
public int getInitialBackgroundColor() {
|
||||
|
||||
return initialBackgroundColor;
|
||||
}
|
||||
|
||||
public int getCurrentBackgroundColor() {
|
||||
|
||||
return currentBackgroundColor;
|
||||
}
|
||||
|
||||
public long getPosition() {
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(int position) {
|
||||
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,11 +9,17 @@ import android.view.ViewGroup;
|
|||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.google.gson.Gson;
|
||||
import com.vdurmont.emoji.Emoji;
|
||||
import com.vdurmont.emoji.EmojiManager;
|
||||
import org.gitnex.tea4j.models.IssueReaction;
|
||||
import org.gitnex.tea4j.models.UserInfo;
|
||||
import org.mian.gitnex.R;
|
||||
import org.mian.gitnex.adapters.ReactionAuthorsAdapter;
|
||||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
|
@ -23,6 +29,7 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
|
@ -63,7 +70,8 @@ public class ReactionList extends HorizontalScrollView {
|
|||
if(bundle.containsKey("commentId")) {
|
||||
id = bundle.getInt("commentId");
|
||||
reactionType = ReactionType.COMMENT;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
id = bundle.getInt("issueId");
|
||||
reactionType = ReactionType.ISSUE;
|
||||
}
|
||||
|
@ -89,17 +97,15 @@ public class ReactionList extends HorizontalScrollView {
|
|||
.getIssueCommentReactions(Authorization.get(context), repoOwner, repoName, id)
|
||||
.execute();
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
Map<String, List<IssueReaction>> sortedReactions = new HashMap<>();
|
||||
if(response.isSuccessful() && response.body() != null && !response.body().isEmpty()) {
|
||||
|
||||
if(response.isSuccessful() && response.body() != null) {
|
||||
Map<String, List<IssueReaction>> sortedReactions = new HashMap<>();
|
||||
|
||||
for(IssueReaction issueReaction : response.body()) {
|
||||
|
||||
if(sortedReactions.containsKey(issueReaction.getContent())) {
|
||||
|
||||
sortedReactions.get(issueReaction.getContent()).add(issueReaction);
|
||||
} else {
|
||||
List<IssueReaction> issueReactions = new ArrayList<>();
|
||||
|
@ -108,30 +114,56 @@ public class ReactionList extends HorizontalScrollView {
|
|||
sortedReactions.put(issueReaction.getContent(), issueReactions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(String content : sortedReactions.keySet()) {
|
||||
for(String content : sortedReactions.keySet()) {
|
||||
|
||||
List<IssueReaction> issueReactions = sortedReactions.get(content);
|
||||
List<IssueReaction> issueReactions = sortedReactions.get(content);
|
||||
|
||||
@SuppressLint("InflateParams") CardView reactionBadge = (CardView) LayoutInflater.from(context)
|
||||
.inflate(R.layout.layout_reaction_badge, this, false);
|
||||
@SuppressLint("InflateParams") CardView reactionBadge = (CardView) LayoutInflater.from(context).inflate(R.layout.layout_reaction_badge, this, false);
|
||||
|
||||
for(IssueReaction issueReaction : issueReactions) {
|
||||
|
||||
if(issueReaction.getUser().getLogin().equals(loginUid)) {
|
||||
reactionBadge.setCardBackgroundColor(AppUtil.getColorFromAttribute(context, R.attr.inputSelectedColor));
|
||||
break;
|
||||
for(IssueReaction issueReaction : issueReactions) {
|
||||
if(issueReaction.getUser().getLogin().equals(loginUid)) {
|
||||
reactionBadge.setCardBackgroundColor(AppUtil.getColorFromAttribute(context, R.attr.inputSelectedColor));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Emoji emoji = EmojiManager.getForAlias(content);
|
||||
|
||||
((TextView) reactionBadge.findViewById(R.id.symbol)).setText(((emoji == null) ? content : emoji.getUnicode()) + " " + issueReactions.size());
|
||||
|
||||
reactionBadge.setOnClickListener(v -> {
|
||||
|
||||
List<UserInfo> userData = issueReactions.stream().map(issueReaction -> {
|
||||
Gson gson = new Gson();
|
||||
return gson.fromJson(gson.toJson(issueReaction.getUser()), UserInfo.class); // FIXME Remove when transitioned to tea4j-autodeploy
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
ReactionAuthorsAdapter adapter = new ReactionAuthorsAdapter(context, userData);
|
||||
|
||||
int paddingTop = AppUtil.getPixelsFromDensity(context, 10);
|
||||
|
||||
RecyclerView recyclerView = new RecyclerView(context);
|
||||
recyclerView.setPadding(0, paddingTop, 0, 0);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(context));
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
assert emoji != null;
|
||||
AlertDialog alertDialog = new AlertDialog.Builder(context)
|
||||
.setView(recyclerView)
|
||||
.setTitle(emoji.getUnicode())
|
||||
.setPositiveButton(R.string.okButton, (dialog, which) -> dialog.cancel())
|
||||
.setCancelable(true)
|
||||
.create();
|
||||
|
||||
alertDialog.show();
|
||||
|
||||
});
|
||||
|
||||
root.post(() -> root.addView(reactionBadge));
|
||||
onReactionAddedListener.reactionAdded();
|
||||
|
||||
}
|
||||
|
||||
Emoji emoji = EmojiManager.getForAlias(content);
|
||||
|
||||
((TextView) reactionBadge.findViewById(R.id.symbol)).setText(((emoji == null) ? content : emoji.getUnicode()) + " " + issueReactions.size());
|
||||
|
||||
root.post(() -> root.addView(reactionBadge));
|
||||
onReactionAddedListener.reactionAdded();
|
||||
|
||||
}
|
||||
|
||||
} catch (IOException ignored) {}
|
||||
|
@ -145,5 +177,4 @@ public class ReactionList extends HorizontalScrollView {
|
|||
}
|
||||
|
||||
public interface OnReactionAddedListener { void reactionAdded(); }
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.mian.gitnex.views;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
|
@ -18,7 +19,6 @@ import org.mian.gitnex.R;
|
|||
import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.Authorization;
|
||||
import org.mian.gitnex.helpers.Constants;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -30,14 +30,16 @@ import retrofit2.Response;
|
|||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
|
||||
@SuppressLint("ViewConstructor")
|
||||
public class ReactionSpinner extends HorizontalScrollView {
|
||||
|
||||
private static final List<String> allowedReactionsCache = new ArrayList<>();
|
||||
|
||||
private enum ReactionType { COMMENT, ISSUE }
|
||||
private enum ReactionAction { REMOVE, ADD }
|
||||
|
||||
private OnInteractedListener onInteractedListener;
|
||||
private Runnable onLoadingFinishedListener;
|
||||
|
||||
public ReactionSpinner(Context context, Bundle bundle) {
|
||||
|
||||
|
@ -45,12 +47,12 @@ public class ReactionSpinner extends HorizontalScrollView {
|
|||
|
||||
LinearLayout root = new LinearLayout(context);
|
||||
|
||||
int dens = AppUtil.getPixelsFromDensity(context, 10);
|
||||
int sidesPadding = AppUtil.getPixelsFromDensity(context, 10);
|
||||
|
||||
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
|
||||
root.setOrientation(LinearLayout.HORIZONTAL);
|
||||
root.setPadding(dens, 0, dens, 0);
|
||||
root.setPadding(sidesPadding, 0, sidesPadding, 0);
|
||||
root.setGravity(Gravity.START);
|
||||
root.setLayoutParams(layoutParams);
|
||||
|
||||
|
@ -76,56 +78,61 @@ public class ReactionSpinner extends HorizontalScrollView {
|
|||
try {
|
||||
|
||||
List<IssueReaction> allReactions = getReactions(repoOwner, repoName, reactionType, id);
|
||||
List<String> allowedReactions = getAllowedReactions();
|
||||
|
||||
for(String allowedReaction : getAllowedReactions()) {
|
||||
if(!allowedReactions.isEmpty()) {
|
||||
// Show all allowed reactions
|
||||
for(String allowedReaction : allowedReactions) {
|
||||
|
||||
@SuppressLint("InflateParams") CardView reactionButton = (CardView) LayoutInflater.from(context)
|
||||
.inflate(R.layout.layout_reaction_button, root, false);
|
||||
@SuppressLint("InflateParams") CardView reactionButton = (CardView) LayoutInflater.from(context)
|
||||
.inflate(R.layout.layout_reaction_button, root, false);
|
||||
|
||||
IssueReaction myReaction = null;
|
||||
// Checks if current user reacted with 'allowedReaction'
|
||||
boolean myReaction = allReactions.stream().anyMatch(issueReaction ->
|
||||
issueReaction.getContent().equals(allowedReaction) &&
|
||||
issueReaction.getUser().getLogin().equals(loginUid));
|
||||
|
||||
for(IssueReaction issueReaction : allReactions) {
|
||||
ReactionAction reactionAction;
|
||||
|
||||
if(issueReaction.getContent().equals(allowedReaction) && issueReaction.getUser().getLogin().equals(loginUid)) {
|
||||
myReaction = issueReaction;
|
||||
break;
|
||||
if(myReaction) {
|
||||
reactionButton.setCardBackgroundColor(AppUtil.getColorFromAttribute(context, R.attr.inputSelectedColor));
|
||||
reactionAction = ReactionAction.REMOVE;
|
||||
} else {
|
||||
reactionAction = ReactionAction.ADD;
|
||||
}
|
||||
|
||||
reactionButton.setOnClickListener(v -> new Thread(() -> {
|
||||
|
||||
try {
|
||||
if(react(repoOwner, repoName, reactionType, reactionAction, new IssueReaction(allowedReaction), id)) {
|
||||
v.post(() -> onInteractedListener.onInteracted());
|
||||
}
|
||||
} catch(IOException ignored) {}
|
||||
|
||||
}).start());
|
||||
|
||||
Emoji emoji = EmojiManager.getForAlias(allowedReaction);
|
||||
|
||||
((TextView) reactionButton.findViewById(R.id.symbol)).setText((emoji == null) ? allowedReaction : emoji.getUnicode());
|
||||
root.post(() -> root.addView(reactionButton));
|
||||
|
||||
}
|
||||
|
||||
ReactionAction reactionAction;
|
||||
|
||||
if(myReaction != null) {
|
||||
|
||||
reactionButton.setCardBackgroundColor(AppUtil.getColorFromAttribute(context, R.attr.inputSelectedColor));
|
||||
reactionAction = ReactionAction.REMOVE;
|
||||
} else {
|
||||
reactionAction = ReactionAction.ADD;
|
||||
}
|
||||
|
||||
reactionButton.setOnClickListener(v -> new Thread(() -> {
|
||||
|
||||
try {
|
||||
if(react(repoOwner, repoName, reactionType, reactionAction, new IssueReaction(allowedReaction), id)) {
|
||||
v.post(() -> onInteractedListener.onInteracted());
|
||||
}
|
||||
} catch(IOException ignored) {}
|
||||
|
||||
}).start());
|
||||
|
||||
Emoji emoji = EmojiManager.getForAlias(allowedReaction);
|
||||
|
||||
((TextView) reactionButton.findViewById(R.id.symbol)).setText((emoji == null) ? allowedReaction : emoji.getUnicode());
|
||||
root.post(() -> root.addView(reactionButton));
|
||||
this.post(() -> {
|
||||
setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
addView(root);
|
||||
setVisibility(VISIBLE);
|
||||
});
|
||||
|
||||
} else {
|
||||
this.post(() -> setVisibility(GONE));
|
||||
}
|
||||
|
||||
} catch(IOException ignored) {}
|
||||
|
||||
if(onLoadingFinishedListener != null) {
|
||||
((Activity) context).runOnUiThread(() -> onLoadingFinishedListener.run());
|
||||
}
|
||||
}).start();
|
||||
|
||||
setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
addView(root);
|
||||
|
||||
}
|
||||
|
||||
private boolean react(String repoOwner, String repoName, ReactionType reactionType, ReactionAction reactionAction, IssueReaction issueReaction, int id) throws IOException {
|
||||
|
@ -204,29 +211,29 @@ public class ReactionSpinner extends HorizontalScrollView {
|
|||
|
||||
}
|
||||
|
||||
if(response.isSuccessful() && response.body() != null)
|
||||
if(response.isSuccessful() && response.body() != null) {
|
||||
return response.body();
|
||||
else
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Assumes that there's something wrong when no allowed reactions are returned by the server
|
||||
private List<String> getAllowedReactions() throws IOException {
|
||||
|
||||
List<String> allowedReactions = new ArrayList<>();
|
||||
if(allowedReactionsCache.isEmpty()) {
|
||||
|
||||
Response<UISettings> response = RetrofitClient
|
||||
.getApiInterface(getContext())
|
||||
.getUISettings(Authorization.get(getContext()))
|
||||
.execute();
|
||||
Response<UISettings> response = RetrofitClient
|
||||
.getApiInterface(getContext())
|
||||
.getUISettings(Authorization.get(getContext()))
|
||||
.execute();
|
||||
|
||||
if(response.isSuccessful() && response.body() != null) {
|
||||
allowedReactions.addAll(Arrays.asList(response.body().getAllowed_reactions()));
|
||||
} else {
|
||||
allowedReactions.addAll(Arrays.asList(Constants.fallbackReactions));
|
||||
if(response.isSuccessful() && response.body() != null) {
|
||||
allowedReactionsCache.addAll(Arrays.asList(response.body().getAllowed_reactions()));
|
||||
}
|
||||
}
|
||||
|
||||
return allowedReactions;
|
||||
return allowedReactionsCache;
|
||||
|
||||
}
|
||||
|
||||
|
@ -236,4 +243,8 @@ public class ReactionSpinner extends HorizontalScrollView {
|
|||
|
||||
public interface OnInteractedListener { void onInteracted(); }
|
||||
|
||||
public void setOnLoadingFinishedListener(Runnable onLoadingFinishedListener) {
|
||||
this.onLoadingFinishedListener = onLoadingFinishedListener;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
10
app/src/main/res/drawable/ic_diff.xml
Normal file
10
app/src/main/res/drawable/ic_diff.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?attr/iconsColor"
|
||||
android:pathData="M12.25,3.5a0.75,0.75 0,0 1,0.75 0.75V8.5h4.25a0.75,0.75 0,0 1,0 1.5H13v4.25a0.75,0.75 0,0 1,-1.5 0V10H7.25a0.75,0.75 0,0 1,0 -1.5h4.25V4.25a0.75,0.75 0,0 1,0.75 -0.75zM6.562,19.25a0.75,0.75 0,0 1,0.75 -0.75h9.938a0.75,0.75 0,0 1,0 1.5H7.312a0.75,0.75 0,0 1,-0.75 -0.75z"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
|
@ -2,7 +2,7 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="2dp" />
|
||||
<corners android:radius="8dp" />
|
||||
<solid
|
||||
android:color="?attr/iconsColor"/>
|
||||
<padding
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="0dp" />
|
||||
<solid
|
||||
android:color="?attr/iconsColor"/>
|
||||
<padding
|
||||
android:bottom="2dp"
|
||||
android:left="5dp"
|
||||
android:right="5dp"
|
||||
android:top="2dp" />
|
||||
|
||||
</shape>
|
13
app/src/main/res/layout/activity_diff.xml
Normal file
13
app/src/main/res/layout/activity_diff.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="?attr/primaryBackgroundColor">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -23,13 +23,13 @@
|
|||
android:id="@+id/close"
|
||||
android:layout_width="@dimen/close_button_size"
|
||||
android:layout_height="@dimen/close_button_size"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:gravity="center_vertical"
|
||||
android:contentDescription="@string/close"
|
||||
android:layout_marginRight="15dp"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:focusable="true"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@string/close"
|
||||
android:focusable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:src="@drawable/ic_close" />
|
||||
|
||||
<TextView
|
||||
|
@ -37,43 +37,29 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:maxLines="1"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="20sp" />
|
||||
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
app:tabIndicatorColor="?attr/pagerTabIndicatorColor"
|
||||
app:tabIndicatorFullWidth="true"
|
||||
app:tabMode="auto"
|
||||
app:tabTextAppearance="@style/customTabLayout"
|
||||
app:tabTextColor="?attr/primaryTextColor" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
|
||||
app:indicatorColor="?attr/progressIndicatorColor" />
|
||||
|
||||
<GridView
|
||||
android:id="@+id/gridView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:horizontalSpacing="10dp"
|
||||
android:numColumns="4"
|
||||
android:columnWidth="80dp"
|
||||
android:stretchMode="columnWidth"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:gravity="center"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/noDataMembers"
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="15dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/noDataMembers"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="20sp"
|
||||
android:visibility="gone" />
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
|
||||
</LinearLayout>
|
|
@ -47,7 +47,6 @@
|
|||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<GridView
|
||||
android:padding="10dp"
|
||||
android:id="@+id/gridView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<GridView
|
||||
android:padding="10dp"
|
||||
android:id="@+id/gridView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -56,7 +55,7 @@
|
|||
android:columnWidth="80dp"
|
||||
android:stretchMode="columnWidth"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:gravity="center"/>
|
||||
android:gravity="center" />
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progress_bar"
|
||||
|
|
|
@ -1,30 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/counterBadgePullText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textSize="16sp"
|
||||
app:textAllCaps="true"
|
||||
android:text="@string/tabPullRequests"
|
||||
android:textColor="@color/lightGray" />
|
||||
android:textColor="@color/lightGray"
|
||||
android:textSize="16sp"
|
||||
app:textAllCaps="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/counterBadgePull"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:layout_toEndOf="@id/counterBadgePullText"
|
||||
android:background="@drawable/shape_badge_background"
|
||||
android:gravity="center"
|
||||
android:text="@string/infoTabRepoZero"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,30 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/counterBadgeReleaseText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textSize="16sp"
|
||||
app:textAllCaps="true"
|
||||
android:text="@string/tabTextReleases"
|
||||
android:textColor="@color/lightGray" />
|
||||
android:textColor="@color/lightGray"
|
||||
android:textSize="16sp"
|
||||
app:textAllCaps="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/counterBadgeRelease"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:layout_toEndOf="@id/counterBadgeReleaseText"
|
||||
android:background="@drawable/shape_badge_background"
|
||||
android:gravity="center"
|
||||
android:text="@string/infoTabRepoZero"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
android:id="@+id/commentReactionButtons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
android:id="@+id/commentReactionButtons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
<TextView
|
||||
|
|
53
app/src/main/res/layout/fragment_diff.xml
Normal file
53
app/src/main/res/layout/fragment_diff.xml
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/Widget.AppCompat.SearchView">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/primaryBackgroundColor">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/close"
|
||||
android:layout_width="@dimen/close_button_size"
|
||||
android:layout_height="@dimen/close_button_size"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@string/close"
|
||||
android:focusable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:src="@drawable/ic_close" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/toolbar_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:ellipsize="start"
|
||||
android:singleLine="true"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="18sp" />
|
||||
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<ListView
|
||||
android:id="@+id/diff"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fastScrollEnabled="true" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1,11 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:background="?attr/primaryBackgroundColor">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
|
@ -50,27 +48,18 @@
|
|||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/filesDiffFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ListView
|
||||
android:id="@+id/listView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:scrollbars="vertical" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progress_bar"
|
||||
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
|
||||
app:indicatorColor="?attr/progressIndicatorColor" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/diff_files"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fastScrollEnabled="true" />
|
||||
|
||||
</LinearLayout>
|
|
@ -19,17 +19,25 @@
|
|||
android:id="@+id/breadcrumbs_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:saveEnabled="false"
|
||||
android:text="@string/filesBreadcrumbRoot"
|
||||
app:CustomTextSize="16sp"
|
||||
app:SelectedTextColor="?attr/primaryTextColor"
|
||||
app:UnSelectedTextColor="@color/lightGray" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/pullToRefresh"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:scrollbars="vertical" />
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:scrollbars="vertical" />
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
|
||||
<GridView
|
||||
android:id="@+id/gridView"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:padding="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:horizontalSpacing="10dp"
|
||||
android:numColumns="4"
|
||||
android:columnWidth="80dp"
|
||||
android:stretchMode="columnWidth"
|
||||
android:gravity="center"/>
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:gravity="center" />
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progressBar"
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progressBar"
|
||||
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
app:indicatorColor="?attr/progressIndicatorColor" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<GridView
|
||||
android:id="@+id/members"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:horizontalSpacing="10dp"
|
||||
android:numColumns="4"
|
||||
android:columnWidth="80dp"
|
||||
android:stretchMode="columnWidth"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:gravity="center"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/noDataMembers"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="15dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/noDataMembers"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="20sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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:background="?attr/primaryBackgroundColor"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progressBar"
|
||||
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
app:indicatorColor="?attr/progressIndicatorColor" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/permissions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="15sp"
|
||||
tools:text="• Members of this team can view team repositories." />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -4,19 +4,19 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
app:cardBackgroundColor="?attr/inputBackgroundColor"
|
||||
app:cardCornerRadius="10dp"
|
||||
app:cardCornerRadius="15dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/symbol"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingTop="3dp"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingBottom="3dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingBottom="5dp"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp"
|
||||
tools:text="👍" />
|
||||
|
|
|
@ -2,13 +2,12 @@
|
|||
<androidx.cardview.widget.CardView 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="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
app:cardBackgroundColor="?attr/inputBackgroundColor"
|
||||
app:cardCornerRadius="25sp"
|
||||
app:cardElevation="0dp"
|
||||
app:contentPadding="10dp">
|
||||
app:cardCornerRadius="20dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/symbol"
|
||||
|
@ -16,7 +15,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="18sp"
|
||||
android:textSize="20dp"
|
||||
tools:ignore="SpUsage"
|
||||
tools:text="👍" />
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
|
9
app/src/main/res/layout/layout_tab_text.xml
Normal file
9
app/src/main/res/layout/layout_tab_text.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:maxLines="1"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="16sp" />
|
|
@ -1,84 +1,96 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/commitList"
|
||||
<LinearLayout 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="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:background="?attr/primaryBackgroundColor">
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayoutFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:padding="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/commitTitleVw"
|
||||
android:id="@+id/commitSubject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/commitTitle"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="18sp"
|
||||
tools:text="This is a test" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/frameCommitterAndDate"
|
||||
<TextView
|
||||
android:id="@+id/commitBody"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:alpha=".8"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp"
|
||||
tools:text="This is a test commit message" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/frameCommitter"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/commitAuthorAvatar"
|
||||
android:layout_width="@dimen/list_avatar_size"
|
||||
android:layout_height="@dimen/list_avatar_size"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
tools:srcCompat="@tools:sample/avatars" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/commitCommitterAvatar"
|
||||
android:layout_width="@dimen/list_avatar_size"
|
||||
android:layout_height="@dimen/list_avatar_size"
|
||||
android:layout_marginStart="5dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
tools:srcCompat="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/commitCommitterVw"
|
||||
android:id="@+id/commitAuthorAndCommitter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp" />
|
||||
tools:text="opyale authored and opyale committed" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/commitDateVw"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:id="@+id/commitSha"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:layout_weight="0"
|
||||
android:alpha=".8"
|
||||
android:drawablePadding="10dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp" />
|
||||
app:drawableLeftCompat="@drawable/ic_commit"
|
||||
tools:text="357f3qd5s" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/frameViewCommits"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/commitHtmlUrlVw"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="60dp"
|
||||
android:text="@string/viewInBrowser"
|
||||
android:layout_marginTop="15dp"
|
||||
android:textColor="@color/btnTextColor"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_below="@id/linearLayoutFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:id="@+id/divider"
|
||||
android:background="?attr/dividerColor" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
|
52
app/src/main/res/layout/list_diff_files.xml
Normal file
52
app/src/main/res/layout/list_diff_files.xml
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="15dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
app:srcCompat="@drawable/ic_diff" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fileName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="start"
|
||||
android:singleLine="true"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="16sp"
|
||||
tools:text="/src/test1/test2/test3/test4/test.txt" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fileStatistics"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="13sp"
|
||||
tools:text="@string/diffStatistics" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@drawable/ic_chevron_right"
|
||||
android:contentDescription="@string/generalImgContentText" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1,108 +0,0 @@
|
|||
<?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="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/shape_files_diffs"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingRight="15dp"
|
||||
android:paddingBottom="7dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/headerFileName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="start"
|
||||
android:fontFamily="monospace"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/diff_stats"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="5dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:background="@color/colorLightGreen"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Space
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0.5" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.5"
|
||||
android:background="@color/colorRed"
|
||||
android:orientation="horizontal" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/headerFileInfo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="monospace"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/dividerColor" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/footer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/footerImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitXY"
|
||||
android:visibility="gone"
|
||||
android:contentDescription="@string/generalImgContentText" />
|
||||
|
||||
<HorizontalScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
tools:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/diffLines"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"/>
|
||||
</HorizontalScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/dividerColor" />
|
||||
|
||||
</LinearLayout>
|
14
app/src/main/res/layout/list_members_by_org_preview.xml
Normal file
14
app/src/main/res/layout/list_members_by_org_preview.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/avatar"
|
||||
android:layout_width="@dimen/list_avatar_size"
|
||||
android:layout_height="@dimen/list_avatar_size"
|
||||
android:contentDescription="@string/generalImgContentText" />
|
||||
|
||||
</LinearLayout>
|
|
@ -4,7 +4,7 @@
|
|||
android:id="@+id/frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:padding="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
@ -21,45 +21,13 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/typePr"
|
||||
android:id="@+id/type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
app:srcCompat="@drawable/ic_pull_request" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/typeIssue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
app:srcCompat="@drawable/ic_issue" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/typeRepo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
app:srcCompat="@drawable/ic_repo" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/typeCommit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
app:srcCompat="@drawable/ic_commit" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/typeUnknown"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
app:srcCompat="@drawable/ic_question" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
|
46
app/src/main/res/layout/list_reaction_authors.xml
Normal file
46
app/src/main/res/layout/list_reaction_authors.xml
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?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="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingRight="15dp"
|
||||
android:paddingBottom="5dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/authorAvatar"
|
||||
android:layout_width="@dimen/list_avatar_size_medium"
|
||||
android:layout_height="@dimen/list_avatar_size_medium"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/authorFullName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="opyale" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/authorLogin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
tools:text="opyale" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -1,36 +1,58 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/orgTeamsFrame"
|
||||
android:padding="16dp"
|
||||
android:orientation="vertical"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/teamTitle"
|
||||
android:text="@string/teamTitle"
|
||||
android:layout_width="match_parent"
|
||||
<TextView
|
||||
android:id="@+id/teamTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/teamTitle"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="PR-Managers" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/teamDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/teamDescription"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="15sp"
|
||||
tools:text="Managing pull requests and related issues" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/membersPreviewFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="bottom"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/membersPreview"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="18sp" />
|
||||
android:layout_weight="1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/teamDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/teamDescription"
|
||||
android:gravity="center_vertical"
|
||||
android:text="@string/teamShowAll"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/teamPermission"
|
||||
android:text="@string/teamPermission"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="15sp"
|
||||
app:drawableEndCompat="@drawable/ic_chevron_right"
|
||||
app:drawableTint="?attr/primaryTextColor" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
<?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:id="@+id/gridViewData"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/primaryBackgroundColor"
|
||||
android:orientation="vertical">
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/userAvatarImageView"
|
||||
|
@ -21,7 +24,7 @@
|
|||
android:gravity="top|center_horizontal"
|
||||
android:layout_marginTop="1dp"
|
||||
android:text="@string/userName"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?attr/primaryTextColor" />
|
||||
android:textColor="?attr/primaryTextColor"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
|
||||
<ImageView
|
||||
android:id="@+id/userAvatar"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_width="@dimen/list_avatar_size_large"
|
||||
android:layout_height="@dimen/list_avatar_size_large"
|
||||
android:contentDescription="@string/generalImgContentText"
|
||||
tools:srcCompat="@tools:sample/avatars" />
|
||||
|
||||
|
|
|
@ -4,4 +4,6 @@
|
|||
<dimen name="fab_padding">15dp</dimen>
|
||||
|
||||
<dimen name="list_avatar_size">24dp</dimen>
|
||||
<dimen name="list_avatar_size_medium">34dp</dimen>
|
||||
<dimen name="list_avatar_size_large">60dp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="versionLow" translatable="false">1.14</string>
|
||||
<string name="versionHigh" translatable="false">1.16</string>
|
||||
<string name="versionLow" translatable="false">1.15</string>
|
||||
<string name="versionHigh" translatable="false">1.17</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -107,8 +107,7 @@
|
|||
<string name="orgCreatedError">Something went wrong, please try again</string>
|
||||
<string name="orgExistsError">Organization already exists</string>
|
||||
|
||||
<string name="binaryFileError">Binary files are not supported yet.</string>
|
||||
<string name="fileTooLarge">This file exceeds the maximum possible diff lines</string>
|
||||
<string name="diffStatistics">%s addition(s) and %s deletion(s)</string>
|
||||
|
||||
<string name="processingText">Processing</string>
|
||||
<string name="search">Search</string>
|
||||
|
@ -300,7 +299,13 @@
|
|||
<string name="noDataTeams">No teams found</string>
|
||||
<string name="teamTitle">Team name</string>
|
||||
<string name="teamDescription">Team desc</string>
|
||||
<string name="teamPermission">Permission : %1$s</string>
|
||||
<string name="teamPermissions">Permissions</string>
|
||||
<string name="teamPermissionNone">• Members of this team do not have any permissions.</string>
|
||||
<string name="teamPermissionRead">• Members of this team can view team repositories.</string>
|
||||
<string name="teamPermissionWrite">• Members of this team can view and push to team repositories.</string>
|
||||
<string name="teamPermissionAdmin">• Members of this team can push to and from team repositories and add collaborators.</string>
|
||||
<string name="teamPermissionOwner">• Members of this team have owner permissions.</string>
|
||||
<string name="teamShowAll">show all</string>
|
||||
<string name="noDataMembers">No members found</string>
|
||||
<string name="orgMember">Org members</string>
|
||||
<string name="orgTeamMembers">Organization team members</string>
|
||||
|
@ -540,8 +545,8 @@
|
|||
<string name="editPrSuccessMessage">Pull Request updated</string>
|
||||
<string name="fileDiffViewHeader">%1$s Files Changed</string>
|
||||
<string name="fileDiffViewHeaderSingle">%1$s File Changed</string>
|
||||
<string name="openFileDiffText">Files Changed</string>
|
||||
<string name="updatePullRequestText">Update Pull Request</string>
|
||||
<string name="openFileDiffText">Show Changed Files</string>
|
||||
<string name="mergePullRequestText">Merge Pull Request</string>
|
||||
<string name="deletePrHeadBranch">Delete head branch</string>
|
||||
<string name="deleteBranchSuccess">Branch deleted successfully</string>
|
||||
|
@ -580,7 +585,8 @@
|
|||
<string name="shareRepository">Share Repository</string>
|
||||
<string name="createRepository">Create Repository</string>
|
||||
<string name="commitTitle">Commits</string>
|
||||
<string name="commitCommittedBy">Committed by %1$s</string>
|
||||
<string name="commitAuthoredByAndCommittedByWhen"><![CDATA[<b>%s</b> authored and <b>%s</b> committed %s]]></string>
|
||||
<string name="commitCommittedByWhen"><![CDATA[<b>%s</b> committed %s]]></string>
|
||||
<string name="viewCommits">View Commits</string>
|
||||
<string name="changelogTitle" translatable="false">Changelog</string>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<changelog>
|
||||
|
||||
<release version="4.2.0" versioncode="415">
|
||||
<release version="4.2.0" versioncode="420">
|
||||
<change>Under development</change>
|
||||
</release>
|
||||
|
||||
|
|
Loading…
Reference in a new issue