Compare commits

...

8 commits

Author SHA1 Message Date
leo
6b44fd4416
code_style: remove unused codes
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
2024-09-24 18:22:18 +08:00
leo
d1d913aa45
fix: do NOT delete .git/rebase-merge and .git/rebase-apply folders (#509) 2024-09-24 18:19:22 +08:00
leo
b9597dc92a
ux: new layout for Staticstics window 2024-09-24 17:06:16 +08:00
leo
6151f4dc5f
refactor: a new way to test if this app should be launched as a SSH askpass client 2024-09-24 15:53:36 +08:00
leo
b6ce2bcc85
git: simplify .gitattributes used by this project 2024-09-24 14:23:54 +08:00
leo
7c176744aa
git: update ignore files/folders 2024-09-24 14:20:15 +08:00
leo
c0f59c441b
feature: allow user to select the chart fill color 2024-09-24 12:14:51 +08:00
leo
de15cb1ff2
ux: use column series instead of line series because change between samples is not linear 2024-09-24 11:02:49 +08:00
10 changed files with 94 additions and 704 deletions

66
.gitattributes vendored
View file

@ -1,78 +1,12 @@
# Auto detect text files and perform LF normalization
# https://www.davidlaing.com/2012/09/19/customise-your-gitattributes-to-become-a-git-ninja/
* text=auto * text=auto
#
# The above will handle all files NOT found below
#
# Documents
*.bibtex text diff=bibtex
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
*.md text *.md text
*.tex text diff=tex
*.adoc text
*.textile text
*.mustache text
*.csv text
*.tab text
*.tsv text
*.txt text
*.sql text
# Graphics
*.png binary *.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.tif binary
*.tiff binary
*.ico binary *.ico binary
# SVG treated as an asset (binary) by default.
*.svg text
# If you want to treat it as binary,
# use the following line instead.
# *.svg binary
*.eps binary
# Scripts
*.bash text eol=lf
*.fish text eol=lf
*.sh text eol=lf *.sh text eol=lf
# These are explicitly windows files and should use crlf
*.bat text eol=crlf *.bat text eol=crlf
*.cmd text eol=crlf *.cmd text eol=crlf
*.ps1 text eol=crlf *.ps1 text eol=crlf
# Serialisation
*.json text *.json text
*.toml text
*.xml text
*.yaml text
*.yml text
# Archives
*.7z binary
*.gz binary
*.tar binary
*.tgz binary
*.zip binary
# Text files where line endings should be preserved
*.patch -text
#
# Exclude files from exporting
#
.gitattributes export-ignore .gitattributes export-ignore
.gitignore export-ignore .gitignore export-ignore

588
.gitignore vendored
View file

@ -1,425 +1,13 @@
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/ .vs/
# Uncomment if you have tasks that create the project's static files in wwwroot .vscode/
#wwwroot/ .idea/
# Visual Studio 2017 auto generated files *.sln.docstates
Generated\ Files/ *.user
*.suo
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Nuke Build - Uncomment if you are using it
.nuke/temp
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace *.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
### Linux ###
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store .DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100 .DocumentRevisions-V100
.fseventsd .fseventsd
.Spotlight-V100 .Spotlight-V100
@ -428,175 +16,14 @@ Icon
.VolumeIcon.icns .VolumeIcon.icns
.com.apple.timemachine.donotpresent .com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### Rider ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
.idea/
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### VisualStudioCode ###
!.vscode/*.code-snippets
# Local History for Visual Studio Code
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
### Windows ###
# Windows thumbnail cache files
Thumbs.db Thumbs.db
Thumbs.db:encryptable Thumbs.db:encryptable
ehthumbs.db ehthumbs.db
ehthumbs_vista.db ehthumbs_vista.db
# Dump file bin/
*.stackdump obj/
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
# Windows shortcuts
*.lnk
### Specifics ###
# Specials
*.zip
archives
package-lock.json
*.private.env.json
**/**/[Dd]ata/*.json
**/**/[Dd]ata/*.csv
# SpecFlow
*.feature.cs
# Azurite
*azurite*.json
# Build Folders
[Pp]ublish
[Oo]utput
[Ss]cripts
[Tt]ests/[Rr]esults
# LibraryManager
**/lib
# BuildBundlerMinifier
*.min.*
*.map
# Sass Output
**/css
# SQLite files
*.db
*.sqlite3
*.sqlite
*.db-journal
*.sqlite3-journal
*.sqlite-journal
*.db-shm
*.db-wal
# SourceGit output files
build/resources/ build/resources/
build/SourceGit/ build/SourceGit/
build/SourceGit.app/ build/SourceGit.app/
@ -605,3 +32,4 @@ build/*.tar.gz
build/*.deb build/*.deb
build/*.rpm build/*.rpm
build/*.AppImage build/*.AppImage
SourceGit.app/

View file

@ -516,20 +516,18 @@ namespace SourceGit
private bool TryLaunchedAsAskpass(IClassicDesktopStyleApplicationLifetime desktop) private bool TryLaunchedAsAskpass(IClassicDesktopStyleApplicationLifetime desktop)
{ {
var launchAsAskpass = Environment.GetEnvironmentVariable("SOURCEGIT_LAUNCH_AS_ASKPASS");
if (launchAsAskpass is not "TRUE")
return false;
var args = desktop.Args; var args = desktop.Args;
if (args == null || args.Length != 1) if (args?.Length > 0)
return false; {
desktop.MainWindow = new Views.Askpass(args[0]);
return true;
}
var param = args[0]; return false;
if (Directory.Exists(param))
return false;
if (!param.StartsWith("enter passphrase", StringComparison.OrdinalIgnoreCase) &&
!param.Contains(" password", StringComparison.OrdinalIgnoreCase))
return false;
desktop.MainWindow = new Views.Askpass(param);
return true;
} }
private void TryLaunchedAsNormal(IClassicDesktopStyleApplicationLifetime desktop) private void TryLaunchedAsNormal(IClassicDesktopStyleApplicationLifetime desktop)

View file

@ -42,7 +42,7 @@ namespace SourceGit.Commands
{ {
var start = new ProcessStartInfo(); var start = new ProcessStartInfo();
start.FileName = Native.OS.GitExecutable; start.FileName = Native.OS.GitExecutable;
start.Arguments = "--no-pager -c core.quotepath=off "; start.Arguments = "--no-pager -c core.quotepath=off -c credential.helper=manager ";
start.UseShellExecute = false; start.UseShellExecute = false;
start.CreateNoWindow = true; start.CreateNoWindow = true;
start.RedirectStandardOutput = true; start.RedirectStandardOutput = true;
@ -56,17 +56,13 @@ namespace SourceGit.Commands
start.Environment.Add("DISPLAY", "required"); start.Environment.Add("DISPLAY", "required");
start.Environment.Add("SSH_ASKPASS", selfExecFile); // Can not use parameter here, because it invoked by SSH with `exec` start.Environment.Add("SSH_ASKPASS", selfExecFile); // Can not use parameter here, because it invoked by SSH with `exec`
start.Environment.Add("SSH_ASKPASS_REQUIRE", "prefer"); start.Environment.Add("SSH_ASKPASS_REQUIRE", "prefer");
start.Environment.Add("SOURCEGIT_LAUNCH_AS_ASKPASS", "TRUE");
// If an SSH private key was provided, sets the environment. // If an SSH private key was provided, sets the environment.
if (!string.IsNullOrEmpty(SSHKey)) if (!string.IsNullOrEmpty(SSHKey))
{
start.Environment.Add("GIT_SSH_COMMAND", $"ssh -o StrictHostKeyChecking=accept-new -i '{SSHKey}'"); start.Environment.Add("GIT_SSH_COMMAND", $"ssh -o StrictHostKeyChecking=accept-new -i '{SSHKey}'");
}
else else
{
start.Environment.Add("GIT_SSH_COMMAND", $"ssh -o StrictHostKeyChecking=accept-new"); start.Environment.Add("GIT_SSH_COMMAND", $"ssh -o StrictHostKeyChecking=accept-new");
start.Arguments += "-c credential.helper=manager ";
}
// Force using en_US.UTF-8 locale to avoid GCM crash // Force using en_US.UTF-8 locale to avoid GCM crash
if (OperatingSystem.IsLinux()) if (OperatingSystem.IsLinux())

View file

@ -67,7 +67,7 @@ namespace SourceGit.Models
} }
else else
{ {
XAxes.Add(new DateTimeAxis(TimeSpan.FromDays(365), v => $"{v:yyyy/MM}") { TextSize = 10 }); XAxes.Add(new DateTimeAxis(TimeSpan.FromDays(30), v => $"{v:yyyy/MM}") { TextSize = 10 });
} }
} }
@ -99,14 +99,12 @@ namespace SourceGit.Models
samples.Add(new DateTimePoint(kv.Key, kv.Value)); samples.Add(new DateTimePoint(kv.Key, kv.Value));
Series.Add( Series.Add(
new LineSeries<DateTimePoint>() new ColumnSeries<DateTimePoint>()
{ {
Values = samples, Values = samples,
Stroke = new SolidColorPaint(SKColors.Green) { StrokeThickness = 1 }, Stroke = null,
Fill = new SolidColorPaint(SKColors.SkyBlue.WithAlpha(90)), Fill = null,
GeometrySize = 8, Padding = 1,
GeometryStroke = new SolidColorPaint(SKColors.Green) { StrokeThickness = 2 },
LineSmoothness = 0,
} }
); );
@ -119,6 +117,12 @@ namespace SourceGit.Models
_mapSamples.Clear(); _mapSamples.Clear();
} }
public void ChangeColor(uint color)
{
if (Series is [ColumnSeries<DateTimePoint> series])
series.Fill = new SolidColorPaint(new SKColor(color));
}
private StaticsticsMode _mode = StaticsticsMode.All; private StaticsticsMode _mode = StaticsticsMode.All;
private Dictionary<string, int> _mapUsers = new Dictionary<string, int>(); private Dictionary<string, int> _mapUsers = new Dictionary<string, int>();
private Dictionary<DateTime, int> _mapSamples = new Dictionary<DateTime, int>(); private Dictionary<DateTime, int> _mapSamples = new Dictionary<DateTime, int>();

View file

@ -14,6 +14,7 @@
<StreamGeometry x:Key="Icons.Clean">M797 829a49 49 0 1049 49 49 49 0 00-49-49zm147-114A49 49 0 10992 764a49 49 0 00-49-49zM928 861a49 49 0 1049 49A49 49 0 00928 861zm-5-586L992 205 851 64l-71 71a67 67 0 00-94 0l235 235a67 67 0 000-94zm-853 128a32 32 0 00-32 50 1291 1291 0 0075 112L288 552c20 0 25 21 8 37l-93 86a1282 1282 0 00120 114l100-32c19-6 28 15 14 34l-40 55c26 19 53 36 82 53a89 89 0 00115-20 1391 1391 0 00256-485l-188-188s-306 224-595 198z</StreamGeometry> <StreamGeometry x:Key="Icons.Clean">M797 829a49 49 0 1049 49 49 49 0 00-49-49zm147-114A49 49 0 10992 764a49 49 0 00-49-49zM928 861a49 49 0 1049 49A49 49 0 00928 861zm-5-586L992 205 851 64l-71 71a67 67 0 00-94 0l235 235a67 67 0 000-94zm-853 128a32 32 0 00-32 50 1291 1291 0 0075 112L288 552c20 0 25 21 8 37l-93 86a1282 1282 0 00120 114l100-32c19-6 28 15 14 34l-40 55c26 19 53 36 82 53a89 89 0 00115-20 1391 1391 0 00256-485l-188-188s-306 224-595 198z</StreamGeometry>
<StreamGeometry x:Key="Icons.Clone">M1280 704c0 141-115 256-256 256H288C129 960 0 831 0 672c0-126 80-232 192-272A327 327 0 01192 384c0-177 143-320 320-320 119 0 222 64 277 160C820 204 857 192 896 192c106 0 192 86 192 192 0 24-5 48-13 69C1192 477 1280 580 1280 704zm-493-128H656V352c0-18-14-32-32-32h-96c-18 0-32 14-32 32v224h-131c-29 0-43 34-23 55l211 211c12 12 33 12 45 0l211-211c20-20 6-55-23-55z</StreamGeometry> <StreamGeometry x:Key="Icons.Clone">M1280 704c0 141-115 256-256 256H288C129 960 0 831 0 672c0-126 80-232 192-272A327 327 0 01192 384c0-177 143-320 320-320 119 0 222 64 277 160C820 204 857 192 896 192c106 0 192 86 192 192 0 24-5 48-13 69C1192 477 1280 580 1280 704zm-493-128H656V352c0-18-14-32-32-32h-96c-18 0-32 14-32 32v224h-131c-29 0-43 34-23 55l211 211c12 12 33 12 45 0l211-211c20-20 6-55-23-55z</StreamGeometry>
<StreamGeometry x:Key="Icons.Code">M853 102H171C133 102 102 133 102 171v683C102 891 133 922 171 922h683C891 922 922 891 922 853V171C922 133 891 102 853 102zM390 600l-48 48L205 512l137-137 48 48L301 512l88 88zM465 819l-66-18L559 205l66 18L465 819zm218-171L634 600 723 512l-88-88 48-48L819 512 683 649z</StreamGeometry> <StreamGeometry x:Key="Icons.Code">M853 102H171C133 102 102 133 102 171v683C102 891 133 922 171 922h683C891 922 922 891 922 853V171C922 133 891 102 853 102zM390 600l-48 48L205 512l137-137 48 48L301 512l88 88zM465 819l-66-18L559 205l66 18L465 819zm218-171L634 600 723 512l-88-88 48-48L819 512 683 649z</StreamGeometry>
<StreamGeometry x:Key="Icons.ColorPicker">M731 331c-28-28-43-27-64-130s-95-136-176-136C244 65 64 265 64 512a447 447 0 00448 447c247 0 450-165 448-412-2-224-186-173-229-215zM246 467a57 57 0 1157 57 57 57 0 01-57-57zm125 215a45 45 0 1145-45 45 45 0 01-45 45zm34-310a71 71 0 1171-71 71 71 0 01-71 71z</StreamGeometry>
<StreamGeometry x:Key="Icons.Commit">M796 471A292 292 0 00512 256a293 293 0 00-284 215H0v144h228A293 293 0 00512 832a291 291 0 00284-217H1024V471h-228M512 688A146 146 0 01366 544A145 145 0 01512 400c80 0 146 63 146 144A146 146 0 01512 688</StreamGeometry> <StreamGeometry x:Key="Icons.Commit">M796 471A292 292 0 00512 256a293 293 0 00-284 215H0v144h228A293 293 0 00512 832a291 291 0 00284-217H1024V471h-228M512 688A146 146 0 01366 544A145 145 0 01512 400c80 0 146 63 146 144A146 146 0 01512 688</StreamGeometry>
<StreamGeometry x:Key="Icons.Compare">M645 448l64 64 220-221L704 64l-64 64 115 115H128v90h628zM375 576l-64-64-220 224L314 960l64-64-116-115H896v-90H262z</StreamGeometry> <StreamGeometry x:Key="Icons.Compare">M645 448l64 64 220-221L704 64l-64 64 115 115H128v90h628zM375 576l-64-64-220 224L314 960l64-64-116-115H896v-90H262z</StreamGeometry>
<StreamGeometry x:Key="Icons.Conflict">M608 0q48 0 88 23t63 63 23 87v70h55q35 0 67 14t57 38 38 57 14 67V831q0 34-14 66t-38 57-57 38-67 13H426q-34 0-66-13t-57-38-38-57-14-66v-70h-56q-34 0-66-14t-57-38-38-57-13-67V174q0-47 23-87T109 23 196 0h412m175 244H426q-46 0-86 22T278 328t-26 85v348H608q47 0 86-22t63-62 25-85l1-348m-269 318q18 0 31 13t13 31-13 31-31 13-31-13-13-31 13-31 31-13m0-212q13 0 22 9t11 22v125q0 14-9 23t-22 10-23-7-11-22l-1-126q0-13 10-23t23-10z</StreamGeometry> <StreamGeometry x:Key="Icons.Conflict">M608 0q48 0 88 23t63 63 23 87v70h55q35 0 67 14t57 38 38 57 14 67V831q0 34-14 66t-38 57-57 38-67 13H426q-34 0-66-13t-57-38-38-57-14-66v-70h-56q-34 0-66-14t-57-38-38-57-13-67V174q0-47 23-87T109 23 196 0h412m175 244H426q-46 0-86 22T278 328t-26 85v348H608q47 0 86-22t63-62 25-85l1-348m-269 318q18 0 31 13t13 31-13 31-31 13-31-13-13-31 13-31 31-13m0-212q13 0 22 9t11 22v125q0 14-9 23t-22 10-23-7-11-22l-1-126q0-13 10-23t23-10z</StreamGeometry>

View file

@ -337,6 +337,12 @@ namespace SourceGit.ViewModels
} }
} }
public uint StatisticsSampleColor
{
get => _statisticsSampleColor;
set => SetProperty(ref _statisticsSampleColor, value);
}
public List<RepositoryNode> RepositoryNodes public List<RepositoryNode> RepositoryNodes
{ {
get; get;
@ -621,5 +627,7 @@ namespace SourceGit.ViewModels
private int _shellOrTerminal = -1; private int _shellOrTerminal = -1;
private int _externalMergeToolType = 0; private int _externalMergeToolType = 0;
private string _externalMergeToolPath = string.Empty; private string _externalMergeToolPath = string.Empty;
private uint _statisticsSampleColor = 0xFF00FF00;
} }
} }

View file

@ -837,32 +837,14 @@ namespace SourceGit.ViewModels
var hasUnsolvedConflict = _workingCopy.SetData(changes); var hasUnsolvedConflict = _workingCopy.SetData(changes);
var inProgress = null as InProgressContext; var inProgress = null as InProgressContext;
var rebaseMergeFolder = Path.Combine(_gitDir, "rebase-merge");
var rebaseApplyFolder = Path.Combine(_gitDir, "rebase-apply");
if (File.Exists(Path.Combine(_gitDir, "CHERRY_PICK_HEAD"))) if (File.Exists(Path.Combine(_gitDir, "CHERRY_PICK_HEAD")))
{
inProgress = new CherryPickInProgress(_fullpath); inProgress = new CherryPickInProgress(_fullpath);
} else if (File.Exists(Path.Combine(_gitDir, "REBASE_HEAD")) && Directory.Exists(Path.Combine(_gitDir, "rebase-merge")))
else if (File.Exists(Path.Combine(_gitDir, "REBASE_HEAD")) && Directory.Exists(rebaseMergeFolder))
{
inProgress = new RebaseInProgress(this); inProgress = new RebaseInProgress(this);
}
else if (File.Exists(Path.Combine(_gitDir, "REVERT_HEAD"))) else if (File.Exists(Path.Combine(_gitDir, "REVERT_HEAD")))
{
inProgress = new RevertInProgress(_fullpath); inProgress = new RevertInProgress(_fullpath);
}
else if (File.Exists(Path.Combine(_gitDir, "MERGE_HEAD"))) else if (File.Exists(Path.Combine(_gitDir, "MERGE_HEAD")))
{
inProgress = new MergeInProgress(_fullpath); inProgress = new MergeInProgress(_fullpath);
}
else
{
if (Directory.Exists(rebaseMergeFolder))
Directory.Delete(rebaseMergeFolder, true);
if (Directory.Exists(rebaseApplyFolder))
Directory.Delete(rebaseApplyFolder, true);
}
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {

View file

@ -1,5 +1,8 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Media;
using Avalonia.Threading; using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
@ -28,6 +31,25 @@ namespace SourceGit.ViewModels
private set => SetProperty(ref _selectedReport, value); private set => SetProperty(ref _selectedReport, value);
} }
public uint SampleColor
{
get => Preference.Instance.StatisticsSampleColor;
set
{
if (value != Preference.Instance.StatisticsSampleColor)
{
Preference.Instance.StatisticsSampleColor = value;
OnPropertyChanged(nameof(SampleBrush));
_selectedReport?.ChangeColor(value);
}
}
}
public IBrush SampleBrush
{
get => new SolidColorBrush(SampleColor);
}
public Statistics(string repo) public Statistics(string repo)
{ {
Task.Run(() => Task.Run(() =>
@ -47,18 +69,15 @@ namespace SourceGit.ViewModels
if (_data == null) if (_data == null)
return; return;
switch (_selectedIndex) var report = _selectedIndex switch
{ {
case 0: 0 => _data.All,
SelectedReport = _data.All; 1 => _data.Month,
break; _ => _data.Week,
case 1: };
SelectedReport = _data.Month;
break; report.ChangeColor(SampleColor);
default: SelectedReport = report;
SelectedReport = _data.Week;
break;
}
} }
private bool _isLoading = true; private bool _isLoading = true;

View file

@ -123,11 +123,26 @@
</ListBoxItem> </ListBoxItem>
</ListBox> </ListBox>
<!-- Color Picker -->
<Border Grid.Row="1" HorizontalAlignment="Right">
<Button Background="Transparent" BorderThickness="0" Width="28" Height="28" Margin="0,0,24,0" VerticalAlignment="Center">
<Button.Flyout>
<Flyout>
<Border Padding="8">
<v:ColorPicker Value="{Binding SampleColor, Mode=TwoWay}"/>
</Border>
</Flyout>
</Button.Flyout>
<Path Width="14" Height="14" Data="{StaticResource Icons.ColorPicker}" Fill="{Binding SampleBrush}"/>
</Button>
</Border>
<!-- Contents --> <!-- Contents -->
<ContentControl Grid.Row="2" Content="{Binding SelectedReport, Mode=OneWay}"> <ContentControl Grid.Row="2" Content="{Binding SelectedReport, Mode=OneWay}" Margin="8,8,8,16">
<ContentControl.DataTemplates> <ContentControl.DataTemplates>
<DataTemplate DataType="m:StatisticsReport"> <DataTemplate DataType="m:StatisticsReport">
<Grid ColumnDefinitions="256,*" Margin="8,8,8,16"> <Grid ColumnDefinitions="256,*">
<Grid Grid.Column="0" RowDefinitions="*,16"> <Grid Grid.Column="0" RowDefinitions="*,16">
<!-- Table By Committer --> <!-- Table By Committer -->
<ListBox Grid.Column="0" <ListBox Grid.Column="0"
@ -185,7 +200,12 @@
</Grid> </Grid>
<!-- Graph --> <!-- Graph -->
<lvc:CartesianChart Grid.Column="1" Margin="16" Series="{Binding Series}" XAxes="{Binding XAxes}" YAxes="{Binding YAxes}" ZoomMode="X"/> <lvc:CartesianChart Grid.Column="1"
Margin="0"
Padding="0"
Series="{Binding Series}"
XAxes="{Binding XAxes}" YAxes="{Binding YAxes}"
ZoomMode="X"/>
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</ContentControl.DataTemplates> </ContentControl.DataTemplates>