[app] Open release in browser

This commit is contained in:
tehcneko 2021-02-10 15:26:49 +08:00
parent 2f0d6da850
commit e1c13f3711
6 changed files with 200 additions and 28 deletions

View File

@ -41,7 +41,6 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayoutMediator;
import java.util.ArrayList;
@ -52,6 +51,7 @@ import io.github.lsposed.manager.R;
import io.github.lsposed.manager.databinding.ActivityModuleDetailBinding;
import io.github.lsposed.manager.databinding.ItemRepoReadmeBinding;
import io.github.lsposed.manager.databinding.ItemRepoRecyclerviewBinding;
import io.github.lsposed.manager.databinding.ItemRepoReleaseBinding;
import io.github.lsposed.manager.databinding.ItemRepoTitleDescriptionBinding;
import io.github.lsposed.manager.repo.RepoLoader;
import io.github.lsposed.manager.repo.model.Collaborator;
@ -117,7 +117,7 @@ public class RepoItemActivity extends BaseActivity {
}
}
private class InformationAdapter extends RecyclerView.Adapter<TitleDescriptionHolder> {
private class InformationAdapter extends RecyclerView.Adapter<InformationAdapter.ViewHolder> {
private final OnlineModule module;
private int rowCount = 0;
@ -140,12 +140,12 @@ public class RepoItemActivity extends BaseActivity {
@NonNull
@Override
public TitleDescriptionHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new TitleDescriptionHolder(ItemRepoTitleDescriptionBinding.inflate(getLayoutInflater(), parent, false));
public InformationAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new InformationAdapter.ViewHolder(ItemRepoTitleDescriptionBinding.inflate(getLayoutInflater(), parent, false));
}
@Override
public void onBindViewHolder(@NonNull TitleDescriptionHolder holder, int position) {
public void onBindViewHolder(@NonNull InformationAdapter.ViewHolder holder, int position) {
if (position == homepageRow) {
holder.title.setText(R.string.module_information_homepage);
holder.description.setText(module.getHomepageUrl());
@ -183,15 +183,27 @@ public class RepoItemActivity extends BaseActivity {
NavUtil.startURL(RepoItemActivity.this, module.getSourceUrl());
}
});
}
@Override
public int getItemCount() {
return rowCount;
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView title;
LinkifyTextView description;
public ViewHolder(ItemRepoTitleDescriptionBinding binding) {
super(binding.getRoot());
title = binding.title;
description = binding.description;
}
}
}
private class ReleaseAdapter extends RecyclerView.Adapter<TitleDescriptionHolder> {
private class ReleaseAdapter extends RecyclerView.Adapter<ReleaseAdapter.ViewHolder> {
private final List<Release> items;
public ReleaseAdapter(List<Release> items) {
@ -200,47 +212,50 @@ public class RepoItemActivity extends BaseActivity {
@NonNull
@Override
public TitleDescriptionHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new TitleDescriptionHolder(ItemRepoTitleDescriptionBinding.inflate(getLayoutInflater(), parent, false));
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(ItemRepoReleaseBinding.inflate(getLayoutInflater(), parent, false));
}
@Override
public void onBindViewHolder(@NonNull TitleDescriptionHolder holder, int position) {
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Release release = items.get(position);
holder.title.setText(release.getName());
holder.description.setText(release.getDescription());
holder.itemView.setOnClickListener(v -> {
holder.openInBrowser.setOnClickListener(v -> NavUtil.startURL(RepoItemActivity.this, release.getUrl()));
List<ReleaseAsset> assets = release.getReleaseAssets();
if (assets != null && !assets.isEmpty()) {
holder.viewAssets.setOnClickListener(v -> {
ArrayList<String> names = new ArrayList<>();
release.getReleaseAssets().forEach(releaseAsset -> names.add(releaseAsset.getName()));
assets.forEach(releaseAsset -> names.add(releaseAsset.getName()));
new MaterialAlertDialogBuilder(RepoItemActivity.this)
.setItems(names.toArray(new String[0]), (dialog, which) -> NavUtil.startURL(RepoItemActivity.this, release.getReleaseAssets().get(which).getDownloadUrl()))
.setItems(names.toArray(new String[0]), (dialog, which) -> NavUtil.startURL(RepoItemActivity.this, assets.get(which).getDownloadUrl()))
.show();
} else {
Snackbar.make(binding.snackbar, "no assets", Snackbar.LENGTH_SHORT).show();
}
});
} else {
holder.viewAssets.setVisibility(View.GONE);
}
}
@Override
public int getItemCount() {
return items.size();
}
}
static class TitleDescriptionHolder extends RecyclerView.ViewHolder {
class ViewHolder extends RecyclerView.ViewHolder {
TextView title;
LinkifyTextView description;
TextView description;
View openInBrowser;
View viewAssets;
public TitleDescriptionHolder(ItemRepoTitleDescriptionBinding binding) {
public ViewHolder(ItemRepoReleaseBinding binding) {
super(binding.getRoot());
title = binding.title;
description = binding.description;
openInBrowser = binding.openInBrowser;
viewAssets = binding.viewAssets;
}
}
}
private class PagerAdapter extends RecyclerView.Adapter<PagerAdapter.ViewHolder> {

View File

@ -0,0 +1,30 @@
<!--
~ This file is part of LSPosed.
~
~ LSPosed is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ LSPosed is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
~
~ Copyright (C) 2020 EdXposed Contributors
~ Copyright (C) 2021 LSPosed Contributors
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M16.5,6v11.5c0,2.21 -1.79,4 -4,4s-4,-1.79 -4,-4V5c0,-1.38 1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5v10.5c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1V6H10v9.5c0,1.38 1.12,2.5 2.5,2.5s2.5,-1.12 2.5,-2.5V5c0,-2.21 -1.79,-4 -4,-4S7,2.79 7,5v12.5c0,3.04 2.46,5.5 5.5,5.5s5.5,-2.46 5.5,-5.5V6h-1.5z" />
</vector>

View File

@ -0,0 +1,30 @@
<!--
~ This file is part of LSPosed.
~
~ LSPosed is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ LSPosed is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
~
~ Copyright (C) 2020 EdXposed Contributors
~ Copyright (C) 2021 LSPosed Contributors
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,4L5,4c-1.11,0 -2,0.9 -2,2v12c0,1.1 0.89,2 2,2h4v-2L5,18L5,8h14v10h-4v2h4c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.89,-2 -2,-2zM12,10l-4,4h3v6h2v-6h3l-4,-4z" />
</vector>

View File

@ -0,0 +1,88 @@
<!--
~ This file is part of LSPosed.
~
~ LSPosed is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ LSPosed is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
~
~ Copyright (C) 2020 EdXposed Contributors
~ Copyright (C) 2021 LSPosed Contributors
-->
<FrameLayout 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="?listItemBackground"
android:clickable="true"
android:focusable="true"
android:minHeight="?attr/listPreferredItemHeight"
android:paddingVertical="16dp"
android:paddingStart="16dp"
android:paddingEnd="24dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/item_root"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="RtlSymmetry">
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItem"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@id/description"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="@tools:sample/lorem" />
<TextView
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceSmall"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="@+id/title"
app:layout_constraintTop_toBottomOf="@id/title"
tools:text="@tools:sample/lorem" />
<com.google.android.material.button.MaterialButton
android:id="@+id/view_assets"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/module_release_view_assets"
app:icon="@drawable/ic_attach_file"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@id/description"
app:layout_constraintTop_toBottomOf="@id/description"
style="@style/Widget.MaterialComponents.Button" />
<com.google.android.material.button.MaterialButton
android:id="@+id/open_in_browser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
app:icon="@drawable/ic_open_in_browser"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/view_assets"
app:layout_constraintTop_toBottomOf="@id/description"
style="@style/Widget.App.Button.OutlinedButton.IconOnly" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@ -154,4 +154,6 @@
<string name="module_information_homepage">Homepage</string>
<string name="module_information_source_url">Source code</string>
<string name="module_information_collaborators">Collaborators</string>
<string name="module_release_view_assets">Assets</string>
<string name="module_release_open_browser">Open in…</string>
</resources>

View File

@ -27,6 +27,13 @@
<item name="switchBarBackgroundDisabled">@color/switchbar_background_light</item>
</style>
<style name="Widget.App.Button.OutlinedButton.IconOnly" parent="Widget.MaterialComponents.Button.OutlinedButton">
<item name="iconPadding">0dp</item>
<item name="android:paddingLeft">12dp</item>
<item name="android:paddingRight">12dp</item>
<item name="android:minWidth">48dp</item>
</style>
<style name="Widget.MaterialComponents.CompoundButton.CheckBox" parent="Widget.AppCompat.CompoundButton.CheckBox" tools:override="true">
<item name="enforceMaterialTheme">true</item>
<item name="useMaterialThemeColors">true</item>