Move files for better organization

This commit is contained in:
2026-02-18 09:24:20 +09:00
parent 6e23371858
commit b197f43341
60 changed files with 32 additions and 63 deletions
+19
View File
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
namespace ReceiptPDFBuilder.Helpers
{
// https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifypropertychanged?view=netframework-4.7.2
class ChangeNotifier : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
+55
View File
@@ -0,0 +1,55 @@
using System;
namespace ReceiptPDFBuilder.Helpers;
class Constants
{
public static string AppVersion = "1.1.0";
public static string[] GetQuotes()
{
// sources:
// https://www.reddit.com/r/dadjokes/comments/1ehid23/dads_of_reddit_whats_a_short_clean_joke_that/
// https://www.thepioneerwoman.com/home-lifestyle/a35617884/best-dad-jokes/
// https://www.today.com/life/dad-jokes-rcna27325
// https://www.microscooters.com.au/blogs/family/100-dad-jokes-that-are-the-best-worst-in-the-book?srsltid=AfmBOopcTDq26iDYUsqaTjvUcVW6yxE-u942tatHC7Arns85unMMNfEO
return [
"When in the crucible of life, always remember to take your friends with you.",
"What do you call a paper airplane that won't fly? Stationary.",
"I used to be addicted to dad jokes, but now I'm all groan up.",
"I used to have a phobia about speed bumps. But I'm slowly getting over it.",
"Be careful trusting stairs. They're always up to something.",
"What do you call a fish with no eye? A fsh",
"How do you throw a party in outer space? You planet.",
"Why don't eggs tell jokes? They might crack up!",
"What do you call a snowman with a six-pack? An abdominal snowman!",
"Why did the math book look sad? Because it had too many problems!",
"I was going to tell you a joke about time travel, but you didn't like it.",
"I'm writing a book about glue, but I'm stuck on the first chapter.",
"If two vegetarians get in an argument, is it still called beef?",
"How do you stop a bull from charging? Cancel its credit card.",
"Why do seagulls fly over the sea? If they flew over the bay, they would be bagels.",
"What vegetable is cool, but not *that* cool? Radish.",
"How you fix a broken pumpkin? With a pumpkin patch.",
"Where do boats go when they're sick? To the dock.",
"Why was the broom late to class? It over-swept.",
"Wanna hear a joke about construction? I'm still workin' on it!",
"Which state has the most streets? Rhode Island.",
"What kind of car does a sheep like to drive? A lamborghini.",
"Where do surfers go for an education? Boarding school.",
"What do you get when you cross a fish with an elephant? Swimming trunks.",
"What did one eye say to the other? “Between us, something smells.”",
"When does a joke become a dad joke? When the punchline becomes apparent.",
"What do you call a cold puppy? A chili dog.",
"Why did the spider go to school? He wanted to be a web designer.",
"I was going to tell a sodium joke, then I thought, “Na.”",
"Did you hear about the two rowboats that got into an argument? It was an oar-deal.",
"What do you call birds that stick together? Velcrows.",
"How do birds learn to fly? They wing it.",
"Humpty Dumpty had a great fall. Summer wasn't too bad either.",
"How does the moon cut his hair? Eclipse it!",
"Why did the candle quit his job? He felt burned out."
];
}
}
+34
View File
@@ -0,0 +1,34 @@
using System.Collections.ObjectModel;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.VisualTree;
using Avalonia.Xaml.Interactions.DragAndDrop;
using ReceiptPDFBuilder.Models;
using ReceiptPDFBuilder.ViewModels;
namespace ReceiptPDFBuilder.Helpers;
class DataGridDropHandler : BaseDataGridDropHandler<ReportFile>
{
// https://wieslawsoltes.github.io/Xaml.Behaviors/articles/drag-and-drop-datagrid/datagrid-drag-and-drop-overview.html
// ...that page's code basically doesn't work in the way you'd expect. so just use the source code sample's code.
protected override bool Validate(DataGrid dg, DragEventArgs e, object? sourceContext, object? targetContext, bool execute)
{
if (sourceContext is not ReportFile sourceItem
|| targetContext is not MainViewModel vm
|| dg.GetVisualAt(e.GetPosition(dg)) is not Control targetControl
|| targetControl.DataContext is not ReportFile targetItem)
{
return false;
}
var items = dg.ItemsSource as ObservableCollection<ReportFile>;
return RunDropAction(dg, e, execute, sourceItem, targetItem, items?? []);
}
protected override ReportFile MakeCopy(ObservableCollection<ReportFile> parentCollection, ReportFile item)
{
// Return a clone of the item if you support Copy operations
return new ReportFile { };
}
}
+32
View File
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Threading;
namespace ReceiptPDFBuilders.Helpers;
public static class ThreadSafeRandom
{
[ThreadStatic] private static Random? Local;
public static Random ThisThreadsRandom
{
get { return Local ?? (Local = new Random(unchecked(Environment.TickCount * 31 + Thread.CurrentThread.ManagedThreadId))); }
}
}
// https://stackoverflow.com/a/1262619/3938401
static class ListExtensions
{
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = ThreadSafeRandom.ThisThreadsRandom.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
+9
View File
@@ -0,0 +1,9 @@
using System.Text.Json.Serialization;
using ReceiptPDFBuilder.Models;
namespace ReceiptPDFBuilder.Helpers;
[JsonSerializable(typeof(Settings))]
[JsonSerializable(typeof(ReportFile))]
[JsonSerializable(typeof(PDFReport))]
internal partial class SourceGenerationContext : JsonSerializerContext { }
+38
View File
@@ -0,0 +1,38 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
namespace ReceiptPDFBuilders.Helpers;
class Utilities
{
public static JsonSerializerOptions GetSerializerOptions()
{
var opts = new JsonSerializerOptions
{
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
};
return opts;
}
public static DateOnly? CheckValidDateInString(string str)
{
// https://stackoverflow.com/a/14918404/3938401
var rgx = new Regex(@"\d{4}-\d{2}-\d{2}");
var mat = rgx.Match(str);
if (mat.Success)
{
var dtStr = mat.ToString();
string[] formats = ["yyyy-MM-dd"];
DateTime parsedDateTime;
var didWork = DateTime.TryParseExact(dtStr, formats, CultureInfo.InvariantCulture,
DateTimeStyles.None, out parsedDateTime);
return didWork ? DateOnly.FromDateTime(parsedDateTime) : null;
}
return null;
}
}