Compare commits

..

No commits in common. "6ffb3bd30c2912c3be47ec4e349a7f4b60925ad5" and "04195c29573525151d85b2a9b2d9761c23df4f3d" have entirely different histories.

13 changed files with 77 additions and 78 deletions

View file

@ -1,67 +1,14 @@
#!/bin/bash #!/bin/bash
set -euo pipefail
# Install deps
sudo apt update -y sudo apt update -y
sudo apt install -y libfuse2 wget file sudo apt install -y libfuse2
wget -O pkg2appimage https://github.com/AppImageCommunity/pkg2appimage/releases/download/continuous/pkg2appimage-1eceb30-x86_64.AppImage
# Get tools chmod a+x pkg2appimage
wget -qO appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage export AppImageOutputArch=$OutputArch
chmod +x appimagetool export OutputPath=$OutputPath64
./pkg2appimage ./pkg2appimage.yml
# x86_64 AppDir mv out/*.AppImage v2rayN-${AppImageOutputArch}.AppImage
APPDIR_X64="AppDir-x86_64" export AppImageOutputArch=$OutputArchArm
rm -rf "$APPDIR_X64" export OutputPath=$OutputPathArm64
mkdir -p "$APPDIR_X64/usr/lib/v2rayN" "$APPDIR_X64/usr/bin" "$APPDIR_X64/usr/share/applications" "$APPDIR_X64/usr/share/pixmaps" ./pkg2appimage ./pkg2appimage.yml
cp -rf "$OutputPath64"/* "$APPDIR_X64/usr/lib/v2rayN" || true mv out/*.AppImage v2rayN-${AppImageOutputArch}.AppImage
[ -f "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_X64/usr/share/pixmaps/v2rayN.png" || true
[ -f "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_X64/v2rayN.png" || true
printf '%s\n' '#!/bin/sh' 'HERE="$(dirname "$(readlink -f "$0")")"' 'cd "$HERE/usr/lib/v2rayN"' 'exec "$HERE/usr/lib/v2rayN/v2rayN" "$@"' > "$APPDIR_X64/AppRun"
chmod +x "$APPDIR_X64/AppRun"
ln -sf usr/lib/v2rayN/v2rayN "$APPDIR_X64/usr/bin/v2rayN"
cat > "$APPDIR_X64/v2rayN.desktop" <<EOF
[Desktop Entry]
Name=v2rayN
Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
Exec=v2rayN
Icon=v2rayN
Terminal=false
Type=Application
Categories=Network;
EOF
install -Dm644 "$APPDIR_X64/v2rayN.desktop" "$APPDIR_X64/usr/share/applications/v2rayN.desktop"
ARCH=x86_64 ./appimagetool "$APPDIR_X64" "v2rayN-${OutputArch}.AppImage"
file "v2rayN-${OutputArch}.AppImage" | grep -q 'x86-64'
# aarch64 AppDir
APPDIR_ARM64="AppDir-aarch64"
rm -rf "$APPDIR_ARM64"
mkdir -p "$APPDIR_ARM64/usr/lib/v2rayN" "$APPDIR_ARM64/usr/bin" "$APPDIR_ARM64/usr/share/applications" "$APPDIR_ARM64/usr/share/pixmaps"
cp -rf "$OutputPathArm64"/* "$APPDIR_ARM64/usr/lib/v2rayN" || true
[ -f "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_ARM64/usr/share/pixmaps/v2rayN.png" || true
[ -f "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_ARM64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_ARM64/v2rayN.png" || true
printf '%s\n' '#!/bin/sh' 'HERE="$(dirname "$(readlink -f "$0")")"' 'cd "$HERE/usr/lib/v2rayN"' 'exec "$HERE/usr/lib/v2rayN/v2rayN" "$@"' > "$APPDIR_ARM64/AppRun"
chmod +x "$APPDIR_ARM64/AppRun"
ln -sf usr/lib/v2rayN/v2rayN "$APPDIR_ARM64/usr/bin/v2rayN"
cat > "$APPDIR_ARM64/v2rayN.desktop" <<EOF
[Desktop Entry]
Name=v2rayN
Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
Exec=v2rayN
Icon=v2rayN
Terminal=false
Type=Application
Categories=Network;
EOF
install -Dm644 "$APPDIR_ARM64/v2rayN.desktop" "$APPDIR_ARM64/usr/share/applications/v2rayN.desktop"
# aarch64 runtime
wget -qO runtime-aarch64 https://github.com/AppImage/AppImageKit/releases/download/continuous/runtime-aarch64
chmod +x runtime-aarch64
# build aarch64 AppImage
ARCH=aarch64 ./appimagetool --runtime-file ./runtime-aarch64 "$APPDIR_ARM64" "v2rayN-${OutputArchArm}.AppImage"
file "v2rayN-${OutputArchArm}.AppImage" | grep -q 'ARM aarch64'

37
pkg2appimage.yml Normal file
View file

@ -0,0 +1,37 @@
app: v2rayN
binpatch: true
ingredients:
script:
- export FileName="v2rayN-${AppImageOutputArch}.zip"
- wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/${FileName}"
- 7z x $FileName -aoa
- cp -rf v2rayN-${AppImageOutputArch}/* $OutputPath
script:
- mkdir -p usr/bin usr/lib
- cp -rf $OutputPath usr/lib/v2rayN
- echo "When this file exists, app will not store configs under this folder" > usr/lib/v2rayN/NotStoreConfigHere.txt
- ln -sf usr/lib/v2rayN/v2rayN usr/bin/v2rayN
- chmod a+x usr/lib/v2rayN/v2rayN
- find usr -type f -exec sh -c 'file "{}" | grep -qi "executable" && chmod +x "{}"' \;
- install -Dm644 usr/lib/v2rayN/v2rayN.png v2rayN.png
- install -Dm644 usr/lib/v2rayN/v2rayN.png usr/share/pixmaps/v2rayN.png
- cat > v2rayN.desktop <<EOF
- [Desktop Entry]
- Name=v2rayN
- Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
- Exec=v2rayN
- Icon=v2rayN
- Terminal=false
- Type=Application
- Categories=Network;
- EOF
- install -Dm644 v2rayN.desktop usr/share/applications/v2rayN.desktop
- cat > AppRun <<\EOF
- #!/bin/sh
- HERE="$(dirname "$(readlink -f "${0}")")"
- cd ${HERE}/usr/lib/v2rayN
- exec ${HERE}/usr/lib/v2rayN/v2rayN $@
- EOF
- chmod a+x AppRun

View file

@ -1,7 +1,7 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<Version>7.14.8</Version> <Version>7.14.7</Version>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>

View file

@ -582,9 +582,9 @@ public class Utils
if (host.StartsWith("#")) if (host.StartsWith("#"))
continue; continue;
var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (hostItem.Length < 2) if (hostItem.Length != 2)
continue; continue;
systemHosts.Add(hostItem[1], hostItem[0]); systemHosts.Add(hostItem.Last(), hostItem.First());
} }
} }
} }

View file

@ -1,6 +1,7 @@
using System.Reactive; using System.Reactive;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat;
namespace ServiceLib.ViewModels; namespace ServiceLib.ViewModels;

View file

@ -1,22 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using DynamicData; using DynamicData;
using DynamicData.Binding; using DynamicData.Binding;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat;
namespace ServiceLib.ViewModels; namespace ServiceLib.ViewModels;
public class ProfilesSelectViewModel : MyReactiveObject public class ProfilesSelectViewModel : MyReactiveObject
{ {
#region private prop #region private prop
private List<ProfileItem> _lstProfile;
private string _serverFilter = string.Empty; private string _serverFilter = string.Empty;
private Dictionary<string, bool> _dicHeaderSort = new(); private Dictionary<string, bool> _dicHeaderSort = new();
private string _subIndexId = string.Empty; private string _subIndexId = string.Empty;
// ConfigType filter state: default include-mode with all types selected // ConfigType filter state: default include-mode with all types selected
private List<EConfigType> _filterConfigTypes = new(); private List<EConfigType> _filterConfigTypes = new();
private bool _filterExclude = false; private bool _filterExclude = false;
#endregion private prop #endregion private prop
@ -61,7 +66,6 @@ public class ProfilesSelectViewModel : MyReactiveObject
_config = AppManager.Instance.Config; _config = AppManager.Instance.Config;
_updateView = updateView; _updateView = updateView;
_subIndexId = _config.SubIndexId ?? string.Empty; _subIndexId = _config.SubIndexId ?? string.Empty;
#region WhenAnyValue && ReactiveCommand #region WhenAnyValue && ReactiveCommand
this.WhenAnyValue( this.WhenAnyValue(
@ -126,7 +130,6 @@ public class ProfilesSelectViewModel : MyReactiveObject
_updateView?.Invoke(EViewAction.CloseWindow, null); _updateView?.Invoke(EViewAction.CloseWindow, null);
return true; return true;
} }
#endregion Actions #endregion Actions
#region Servers && Groups #region Servers && Groups
@ -165,6 +168,7 @@ public class ProfilesSelectViewModel : MyReactiveObject
private async Task RefreshServersBiz() private async Task RefreshServersBiz()
{ {
var lstModel = await GetProfileItemsEx(_subIndexId, _serverFilter); var lstModel = await GetProfileItemsEx(_subIndexId, _serverFilter);
_lstProfile = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(lstModel)) ?? [];
ProfileItems.Clear(); ProfileItems.Clear();
ProfileItems.AddRange(lstModel); ProfileItems.AddRange(lstModel);
@ -207,6 +211,9 @@ public class ProfilesSelectViewModel : MyReactiveObject
private async Task<List<ProfileItemModel>?> GetProfileItemsEx(string subid, string filter) private async Task<List<ProfileItemModel>?> GetProfileItemsEx(string subid, string filter)
{ {
var lstModel = await AppManager.Instance.ProfileItems(_subIndexId, filter); var lstModel = await AppManager.Instance.ProfileItems(_subIndexId, filter);
//await ConfigHandler.SetDefaultServer(_config, lstModel);
lstModel = (from t in lstModel lstModel = (from t in lstModel
select new ProfileItemModel select new ProfileItemModel
{ {

View file

@ -13,7 +13,6 @@ public class RoutingRuleSettingViewModel : MyReactiveObject
[Reactive] [Reactive]
public RoutingItem SelectedRouting { get; set; } public RoutingItem SelectedRouting { get; set; }
public IObservableCollection<RulesItemModel> RulesItems { get; } = new ObservableCollectionExtended<RulesItemModel>(); public IObservableCollection<RulesItemModel> RulesItems { get; } = new ObservableCollectionExtended<RulesItemModel>();
[Reactive] [Reactive]

View file

@ -1,12 +1,17 @@
using System.Linq;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Threading.Tasks;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.Markup.Xaml;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using Avalonia.ReactiveUI;
using ReactiveUI; using ReactiveUI;
using ServiceLib.Manager; using ServiceLib.Manager;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views; namespace v2rayN.Desktop.Views;

View file

@ -3,6 +3,7 @@ using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using ReactiveUI; using ReactiveUI;
using v2rayN.Desktop.Base; using v2rayN.Desktop.Base;
using System.Threading.Tasks;
namespace v2rayN.Desktop.Views; namespace v2rayN.Desktop.Views;

View file

@ -3,6 +3,7 @@ using Avalonia;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using ReactiveUI; using ReactiveUI;
using v2rayN.Desktop.Base; using v2rayN.Desktop.Base;
using System.Threading.Tasks;
namespace v2rayN.Desktop.Views; namespace v2rayN.Desktop.Views;

View file

@ -3,8 +3,10 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Threading;
using ReactiveUI; using ReactiveUI;
using ServiceLib.Manager; using ServiceLib.Manager;
using Splat;
using v2rayN.Base; using v2rayN.Base;
namespace v2rayN.Views; namespace v2rayN.Views;
@ -32,6 +34,7 @@ public partial class ProfilesSelectWindow
ViewModel = new ProfilesSelectViewModel(UpdateViewHandler); ViewModel = new ProfilesSelectViewModel(UpdateViewHandler);
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.OneWayBind(ViewModel, vm => vm.ProfileItems, v => v.lstProfiles.ItemsSource).DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.ProfileItems, v => v.lstProfiles.ItemsSource).DisposeWith(disposables);
@ -41,8 +44,6 @@ public partial class ProfilesSelectWindow
this.Bind(ViewModel, vm => vm.SelectedSub, v => v.lstGroup.SelectedItem).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSub, v => v.lstGroup.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.ServerFilter, v => v.txtServerFilter.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.ServerFilter, v => v.txtServerFilter.Text).DisposeWith(disposables);
}); });
WindowsUtils.SetDarkBorder(this, AppManager.Instance.Config.UiItem.CurrentTheme);
} }
public void AllowMultiSelect(bool allow) public void AllowMultiSelect(bool allow)
@ -189,6 +190,5 @@ public partial class ProfilesSelectWindow
// Trigger selection finalize when Confirm is clicked // Trigger selection finalize when Confirm is clicked
ViewModel?.SelectFinish(); ViewModel?.SelectFinish();
} }
#endregion Event #endregion Event
} }

View file

@ -119,7 +119,7 @@ public partial class ProfilesView
if (obj is null) if (obj is null)
return false; return false;
WindowsUtils.SetClipboardData((string)obj); WindowsUtils.SetClipboardData((string)obj);
break; break;
case EViewAction.ProfilesFocus: case EViewAction.ProfilesFocus:
lstProfiles.Focus(); lstProfiles.Focus();

View file

@ -1,5 +1,6 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Threading;
using ReactiveUI; using ReactiveUI;
using ServiceLib.Manager; using ServiceLib.Manager;