mirror of
https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies.git
synced 2026-07-26 14:51:42 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e401bcccfd | |||
| 195ac95b36 | |||
| d1f660381e | |||
| c8aa7ba8e7 | |||
| 50a7d21d52 | |||
| aa092bdd67 | |||
| 6a1b03163c |
@@ -0,0 +1,108 @@
|
||||
name: Build and Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref == 'refs/heads/master'
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: "8.x"
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore NebulaAuth.sln
|
||||
|
||||
- name: Build
|
||||
run: dotnet build NebulaAuth.sln --configuration Release
|
||||
|
||||
- name: Get version from assembly
|
||||
id: get-version
|
||||
shell: pwsh
|
||||
run: |
|
||||
$content = Get-Content -Path "NebulaAuth/NebulaAuth.csproj" -Raw
|
||||
$version = [regex]::Match($content, '<AssemblyVersion>(.*?)<\/AssemblyVersion>').Groups[1].Value
|
||||
Write-Output "VERSION=$version" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Check if tag exists
|
||||
id: tag_exists
|
||||
run: |
|
||||
if (git tag -l | Select-String -Pattern "^${env:VERSION}$") {
|
||||
Write-Output "Version $env:VERSION already exists."
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Check changelog
|
||||
run: |
|
||||
if (-not (Test-Path "changelog/${env:VERSION}.html")) {
|
||||
Write-Output "Changelog file changelog/${env:VERSION}.html does not exist."
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Insert date into changelog
|
||||
run: |
|
||||
$date = Get-Date -Format "dd.MM.yyyy"
|
||||
(Get-Content "changelog/${env:VERSION}.html") -replace '(?<=<div class="date">).*?(?=</div>)', $date | Set-Content "changelog/${env:VERSION}.html"
|
||||
|
||||
- name: Extract changelog description
|
||||
id: extract_description
|
||||
run: |
|
||||
$description = (Get-Content "changelog/${env:VERSION}.html" | Select-String -Pattern '(?<=<div class="description">).*?(?=</div>)' | ForEach-Object { $_.Matches.Value }) -replace '<br\/>', "`n"
|
||||
Write-Output "DESCRIPTION=$description" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Create ZIP
|
||||
run: |
|
||||
New-Item -ItemType Directory -Path release -Force
|
||||
Compress-Archive -Path NebulaAuth/bin/Release -DestinationPath release/NebulaAuth.${env:VERSION}.zip
|
||||
|
||||
- name: Create GitHub Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ env.VERSION }}
|
||||
release_name: NebulaAuth ${{ env.VERSION }}
|
||||
body: |
|
||||
${{ env.DESCRIPTION }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
- name: Upload Release Asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: release/NebulaAuth.${{ env.VERSION }}.zip
|
||||
asset_name: NebulaAuth.${{ env.VERSION }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Update XML and Changelog html
|
||||
shell: pwsh
|
||||
run: |
|
||||
$xmlContent = @"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>${env:VERSION}.0</version>
|
||||
<url>https://github.com/${env:GITHUB_REPOSITORY}/releases/download/${env:VERSION}/NebulaAuth.${env:VERSION}.zip</url>
|
||||
<changelog>https://achiez.github.io/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/changelog/${env:VERSION}.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
</item>
|
||||
"@
|
||||
$xmlContent | Out-File -FilePath update.xml -Encoding UTF8 -Force
|
||||
|
||||
git config --global user.name 'github-actions'
|
||||
git config --global user.email 'github-actions@github.com'
|
||||
git add changelog/${env:VERSION}.html update.xml
|
||||
git commit -m "Update version to ${env:VERSION} and add changelog"
|
||||
git push origin master
|
||||
@@ -22,6 +22,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "changelog", "changelog", "{
|
||||
changelog\1.4.8.html = changelog\1.4.8.html
|
||||
changelog\1.4.9.html = changelog\1.4.9.html
|
||||
changelog\1.5.0.html = changelog\1.5.0.html
|
||||
changelog\1.5.1.html = changelog\1.5.1.html
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
|
||||
@@ -22,7 +22,7 @@ public partial class App : Application
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = ex.Message;
|
||||
var msg = ex.ToString();
|
||||
if (ex is CantAlignTimeException)
|
||||
{
|
||||
msg = Loc.Tr(LocManager.GetCodeBehind("CantAlignTimeError"));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using AchiesUtilities.Collections;
|
||||
using AchiesUtilities.Web.Proxy;
|
||||
@@ -11,6 +12,7 @@ namespace NebulaAuth.Model;
|
||||
|
||||
public static class ProxyStorage
|
||||
{
|
||||
|
||||
public const string FORMAT = ADDRESS_FORMAT + ":{USER}:{PASS}";
|
||||
public const string ADDRESS_FORMAT = "{IP}:{PORT}";
|
||||
|
||||
@@ -32,7 +34,7 @@ public static class ProxyStorage
|
||||
try
|
||||
{
|
||||
var json = File.ReadAllText("proxies.json");
|
||||
var proxies = JsonConvert.DeserializeObject<Proxies>(json) ?? throw new NullReferenceException();
|
||||
var proxies = JsonConvert.DeserializeObject<ProxiesSchema>(json) ?? throw new NullReferenceException();
|
||||
Proxies = proxies.ProxiesData;
|
||||
Proxies = new ObservableDictionary<int, ProxyData>(
|
||||
Proxies.OrderBy(p => p.Key)
|
||||
@@ -48,16 +50,13 @@ public static class ProxyStorage
|
||||
SnackbarController.SendSnackbar("Ошибка при загрузке прокси");
|
||||
SnackbarController.SendSnackbar(ex.Message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void SetProxy(int? id, ProxyData proxyData)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
if (Proxies.Any() == false)
|
||||
if (Proxies.Count == 0)
|
||||
{
|
||||
id = 0;
|
||||
}
|
||||
@@ -71,6 +70,41 @@ public static class ProxyStorage
|
||||
|
||||
Save();
|
||||
}
|
||||
|
||||
public static void SetProxies(IEnumerable<KeyValuePair<int?, ProxyData>> proxies)
|
||||
{
|
||||
foreach (var (key, proxyData) in proxies)
|
||||
{
|
||||
var id = key;
|
||||
if (id == null)
|
||||
{
|
||||
if (Proxies.Count == 0)
|
||||
{
|
||||
id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
id = Proxies.Keys.Max() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
Proxies[id] = proxyData;
|
||||
}
|
||||
|
||||
Save();
|
||||
}
|
||||
|
||||
public static void OrderCollection() //RETHINK: maybe there is better way to handle it
|
||||
{
|
||||
var proxies = Proxies.OrderBy(p => p.Key)
|
||||
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||
Proxies.Clear();
|
||||
foreach (var kvp in proxies)
|
||||
{
|
||||
Proxies.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveProxy(int id)
|
||||
{
|
||||
Proxies.Remove(id);
|
||||
@@ -78,7 +112,7 @@ public static class ProxyStorage
|
||||
}
|
||||
public static bool CompareProxy(ProxyData proxyData1, ProxyData proxyData2)
|
||||
{
|
||||
return proxyData1.Address == proxyData2.Address && proxyData1.Port == proxyData2.Port;
|
||||
return proxyData1.Equals(proxyData2);
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +128,7 @@ public static class ProxyStorage
|
||||
return proxyData.AuthEnabled ? proxyData.ToString(FORMAT) : proxyData.ToString(ADDRESS_FORMAT);
|
||||
}
|
||||
|
||||
private static Proxies Create()
|
||||
private static ProxiesSchema Create()
|
||||
{
|
||||
int? def = null;
|
||||
if (MaClient.DefaultProxy != null)
|
||||
@@ -106,18 +140,16 @@ public static class ProxyStorage
|
||||
}
|
||||
}
|
||||
|
||||
return new Proxies
|
||||
return new ProxiesSchema
|
||||
{
|
||||
ProxiesData = Proxies,
|
||||
DefaultProxy = def
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class Proxies
|
||||
{
|
||||
public ObservableDictionary<int, ProxyData> ProxiesData { get; set; }
|
||||
public int? DefaultProxy { get; set; }
|
||||
private class ProxiesSchema
|
||||
{
|
||||
public ObservableDictionary<int, ProxyData> ProxiesData = new();
|
||||
public int? DefaultProxy;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<SatelliteResourceLanguages>ru</SatelliteResourceLanguages>
|
||||
<ApplicationIcon>Theme\nebula lock.ico</ApplicationIcon>
|
||||
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
|
||||
<AssemblyVersion>1.4.0</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Theme\Background.jpg" />
|
||||
<None Remove="Theme\nebula lock.ico" />
|
||||
<None Remove="Theme\nebula.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.1.0" />
|
||||
<PackageReference Include="MaterialDesignColors" Version="2.1.4" />
|
||||
<PackageReference Include="MaterialDesignExtensions" Version="3.3.0" />
|
||||
<PackageReference Include="MaterialDesignThemes" Version="4.9.0" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
|
||||
<PackageReference Include="NLog" Version="5.1.2" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Resource Include="Theme\Background.jpg">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Theme\nebula lock.ico" />
|
||||
<Resource Include="Theme\nebula.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Model\Utility\" />
|
||||
<Folder Include="Model\Exceptions\" />
|
||||
<Folder Include="Theme\Fonts\Новая папка\" />
|
||||
<Folder Include="ViewModel\Other\" />
|
||||
<Folder Include="Utility\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\SteamLib\SteamLib\SteamLib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="NLog.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -10,7 +10,7 @@
|
||||
<SatelliteResourceLanguages>en;ru;ua</SatelliteResourceLanguages>
|
||||
<ApplicationIcon>Theme\lock.ico</ApplicationIcon>
|
||||
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
|
||||
<AssemblyVersion>1.5.0</AssemblyVersion>
|
||||
<AssemblyVersion>1.5.1</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -76,7 +76,7 @@ public partial class MainVM
|
||||
|
||||
var selectedId = SelectedProxy.Id;
|
||||
ProxyExist = ProxyStorage.Proxies.TryGetValue(selectedId, out var existedProxy)
|
||||
&& ProxyStorage.CompareProxy(SelectedProxy.Data, existedProxy);
|
||||
&& SelectedProxy.Data.Equals(existedProxy); //Id is not important in 'Equals()' as we extract it from the dictionary
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -98,7 +98,7 @@ public partial class MainVM
|
||||
[RelayCommand]
|
||||
private void RemoveProxy()
|
||||
{
|
||||
if(SelectedProxy == null) return;
|
||||
if (SelectedProxy == null) return;
|
||||
if (SelectedMafile == null) return;
|
||||
if (!ValidateCanSaveAndWarn(SelectedMafile)) return;
|
||||
SelectedMafile.Proxy = null;
|
||||
@@ -121,7 +121,7 @@ public partial class MainVM
|
||||
SelectedMafile.Proxy = SelectedProxy;
|
||||
Storage.UpdateMafile(SelectedMafile);
|
||||
}
|
||||
|
||||
|
||||
private bool ValidateCanSaveAndWarn(Mafile data)
|
||||
{
|
||||
var canSave = Storage.ValidateCanSave(data);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using AchiesUtilities.Collections;
|
||||
using AchiesUtilities.Web.Proxy;
|
||||
using AutoUpdaterDotNET;
|
||||
using CodingSeb.Localization.WPF;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using NebulaAuth.Core;
|
||||
@@ -23,7 +21,7 @@ public partial class ProxyManagerVM : ObservableObject
|
||||
[ObservableProperty] private KeyValuePair<int, ProxyData>? _defaultProxy;
|
||||
public ObservableDictionary<int, ProxyData> Proxies => ProxyStorage.Proxies;
|
||||
|
||||
private static readonly Regex IdRegex = new(@"(?:\{(\d+)\})");
|
||||
private static readonly Regex IdRegex = new(@"\{(\d+)\}$");
|
||||
|
||||
|
||||
public ProxyManagerVM()
|
||||
@@ -35,74 +33,71 @@ public partial class ProxyManagerVM : ObservableObject
|
||||
[RelayCommand]
|
||||
private void AddProxy()
|
||||
{
|
||||
if (string.IsNullOrEmpty(AddProxyField)) return;
|
||||
if (AddProxyField.Contains(Environment.NewLine))
|
||||
{
|
||||
var split = AddProxyField.Split(Environment.NewLine);
|
||||
var idPresent = (bool?)null;
|
||||
var proxies = new List<KeyValuePair<int?, ProxyData>>();
|
||||
var i = 0;
|
||||
foreach (var str in split.Where(s => string.IsNullOrWhiteSpace(s) == false))
|
||||
{
|
||||
i++;
|
||||
int? id = null;
|
||||
var match = IdRegex.Match(str);
|
||||
if (match.Success) id = int.Parse(match.Groups[1].Value);
|
||||
idPresent ??= match.Success;
|
||||
|
||||
if (idPresent.Value != match.Success)
|
||||
{
|
||||
SnackbarController.SendSnackbar(GetLocalizationOrDefault("WrongFormatSomeIdsMissing"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (ProxyStorage.DefaultScheme.TryParse(str, out var proxy))
|
||||
{
|
||||
if (id != null && proxies.Any(kvp => kvp.Key == id))
|
||||
{
|
||||
SnackbarController.SendSnackbar(string.Format(GetLocalizationOrDefault("DuplicateId"), id));
|
||||
return;
|
||||
}
|
||||
proxies.Add(new KeyValuePair<int?, ProxyData>(id, proxy));
|
||||
}
|
||||
else
|
||||
{
|
||||
SnackbarController.SendSnackbar(string.Format(GetLocalizationOrDefault("WrongFormatOnLine"), i));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var kvp in proxies)
|
||||
{
|
||||
ProxyStorage.SetProxy(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
var input = AddProxyField;
|
||||
if (string.IsNullOrEmpty(input)) return;
|
||||
|
||||
|
||||
var split = input
|
||||
.Split(Environment.NewLine)
|
||||
.Where(s => string.IsNullOrWhiteSpace(s) == false)
|
||||
.ToArray();
|
||||
|
||||
if (split.Length == 0) return;
|
||||
|
||||
bool? idPresent = null;
|
||||
var proxies = new List<KeyValuePair<int?, ProxyData>>();
|
||||
var i = 0;
|
||||
|
||||
|
||||
foreach (var s in split.Where(s => string.IsNullOrWhiteSpace(s) == false))
|
||||
{
|
||||
i++;
|
||||
var str = s;
|
||||
int? id = null;
|
||||
var input = AddProxyField;
|
||||
if (IdRegex.IsMatch(AddProxyField))
|
||||
var idMatch = IdRegex.Match(str);
|
||||
if (idMatch.Success)
|
||||
{
|
||||
id = int.Parse(IdRegex.Match(AddProxyField).Groups[1].Value);
|
||||
input = IdRegex.Replace(input, "");
|
||||
id = int.Parse(idMatch.Groups[1].Value);
|
||||
str = IdRegex.Replace(str, "");
|
||||
}
|
||||
|
||||
if (ProxyStorage.DefaultScheme.TryParse(input, out var data))
|
||||
idPresent ??= idMatch.Success;
|
||||
if (idPresent.Value != idMatch.Success)
|
||||
{
|
||||
ProxyStorage.SetProxy(id, data);
|
||||
SnackbarController.SendSnackbar(GetLocalizationOrDefault("WrongFormatSomeIdsMissing"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (ProxyStorage.DefaultScheme.TryParse(str, out var proxy))
|
||||
{
|
||||
if (id != null && proxies.Any(kvp => kvp.Key == id))
|
||||
{
|
||||
SnackbarController.SendSnackbar(string.Format(GetLocalizationOrDefault("DuplicateId"), id));
|
||||
return;
|
||||
}
|
||||
proxies.Add(new KeyValuePair<int?, ProxyData>(id, proxy));
|
||||
}
|
||||
else
|
||||
{
|
||||
SnackbarController.SendSnackbar(GetLocalizationOrDefault("WrongFormat"));
|
||||
if (split.Length == 1)
|
||||
{
|
||||
SnackbarController.SendSnackbar(GetLocalizationOrDefault("WrongFormat"));
|
||||
return;
|
||||
}
|
||||
SnackbarController.SendSnackbar(string.Format(GetLocalizationOrDefault("WrongFormatOnLine"), i));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ProxyStorage.SetProxies(proxies);
|
||||
ProxyStorage.OrderCollection();
|
||||
AddProxyField = string.Empty;
|
||||
CheckIfDefaultProxyStay();
|
||||
}
|
||||
|
||||
|
||||
private void CheckIfDefaultProxyStay()
|
||||
{
|
||||
if (!DefaultProxy.HasValue || Proxies.Any(kvp => kvp.Equals(DefaultProxy.Value))) return;
|
||||
@@ -132,7 +127,7 @@ public partial class ProxyManagerVM : ObservableObject
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ProxyStorage.RemoveProxy(s.Key);
|
||||
SelectedProxy = nextNeighbor ?? prevNeighbor;
|
||||
CheckIfDefaultProxyStay();
|
||||
@@ -167,7 +162,7 @@ public partial class ProxyManagerVM : ObservableObject
|
||||
{
|
||||
Shell.Logger.Error(ex);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.5.0.0</version>
|
||||
<url>https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/releases/download/1.5.0/NebulaAuth.1.5.0.zip</url>
|
||||
<changelog>https://achiez.github.io/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/changelog/1.5.0.html</changelog>
|
||||
<version>1.5.1.0</version>
|
||||
<url>https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/releases/download/1.5.1/NebulaAuth.1.5.1.zip</url>
|
||||
<changelog>https://achiez.github.io/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/changelog/1.5.1.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
</item>
|
||||
@@ -0,0 +1,80 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Changelog</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #eeeeee;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.changelog-container {
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 25px;
|
||||
margin: 25px auto;
|
||||
max-width: 800px;
|
||||
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.change {
|
||||
margin-bottom: 20px;
|
||||
padding: 0;
|
||||
border-left: 4px solid #a50ec7;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.version {
|
||||
font-weight: 600;
|
||||
font-size: 1.5em;
|
||||
color: #a50ec7;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-style: italic;
|
||||
color: #888;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1em;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.description ul {
|
||||
list-style: inside square;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
.changelog-container {
|
||||
width: 90%;
|
||||
margin: 25px auto;
|
||||
padding: 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="changelog-container">
|
||||
<!-- Changelog entry -->
|
||||
<div class="change">
|
||||
<div class="version">Version 1.5.1</div>
|
||||
<div class="date">DATE</div>
|
||||
<div class="description">
|
||||
- FIX: Fixed proxy error (407) when {id} was parsed as a part of password when using 'ip:port:username:password{id}' proxy format <br />
|
||||
- IMPROVEMENT: Now proxies always ordered by ID <br />
|
||||
- FIX: Small fix in the proxy comparison method (sometimes proxy red indicator was not shown)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user