Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Bug report
description: Report a reproducible ToastFish problem.
title: "[Bug]: "
labels: ["bug"]
body:
- type: textarea
id: summary
attributes:
label: Summary
description: What happened?
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to reproduce
description: List the exact steps that trigger the problem.
placeholder: |
1. Open ToastFish
2. Select ...
3. Click ...
validations:
required: true
- type: input
id: version
attributes:
label: ToastFish version
placeholder: v3.0.1-community.1
- type: input
id: windows
attributes:
label: Windows version
placeholder: Windows 11 23H2
- type: textarea
id: logs
attributes:
label: Error details or screenshots
description: Paste exception text or attach screenshots if available.
24 changes: 24 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Feature request
description: Suggest an improvement for ToastFish.
title: "[Feature]: "
labels: ["enhancement"]
body:
- type: textarea
id: problem
attributes:
label: Problem
description: What problem would this feature solve?
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposed solution
description: What behavior do you expect?
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives
description: Any workaround or alternative design you have considered?
11 changes: 11 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Summary

-

## Verification

-

## Related Issues

-
71 changes: 20 additions & 51 deletions .github/workflows/dotnet-desktop.yml
Original file line number Diff line number Diff line change
@@ -1,65 +1,34 @@
name: .NET Core Desktop
name: Windows Build

on:
push:
branches: [ main ]
branches: [main]
pull_request:
branches: [ main ]
branches: [main]
workflow_dispatch:

jobs:

build:

strategy:
matrix:
configuration: [Debug, Release]

runs-on: windows-latest

steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0

# Install .NET Core
- name: Install .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.202

# Setup MSBuild.exe
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2

# Setup NuGet
- name: Setup NuGet
uses: nuget/setup-nuget@v1
with:
nuget-api-key: ${{ secrets.NuGetAPIKey }}
nuget-version: '5.x'
- name: Checkout
uses: actions/checkout@v4

# NuGet restore
- name: NuGet restore
run: nuget restore
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2

# Build
- name: Build the solution
run: msbuild /p:Configuration=$env:Configuration
env:
Configuration: ${{ matrix.configuration }}
- name: Setup NuGet
uses: nuget/setup-nuget@v2

# Execute unit tests
- name: Execute unit tests
run: dotnet test -c $env:Configuration
env:
Configuration: ${{ matrix.configuration }}

# Upload bin directory
- name: Upload bin directory
uses: actions/upload-artifact@main
if: ${{ success() }}
with:
name: ToastFish_Build
path: ./bin/Release/
- name: Restore packages
run: nuget restore ToastFish.sln

- name: Build
run: msbuild ToastFish.sln /p:Configuration=Release /p:Platform="Any CPU"

- name: Upload Release build
uses: actions/upload-artifact@v4
with:
name: ToastFish-Release
path: bin/Release/**
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@ obj/
bin/
token.txt
.vs/
.github/
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Changelog

All notable changes in this community fork are documented here.

## v3.0.1-community.1 - Unreleased

### Fixed

- Ensure the `Log` directory exists before learning or import flows write logs.
- Harden Excel import against unreadable files, empty rows, empty cells, and null import results.
- Fix Japanese word progress lookup by quoting the selected book name in SQL.

### Changed

- Clarified community fork status in README.
- Added maintenance roadmap.
- Updated GitHub Actions workflow for current Windows runners.

### Known Issues

- This remains a Windows-only WPF/.NET Framework application.
- Some notification behavior depends on Windows notification settings.
- macOS/Linux support is not planned for the first maintenance cycle.
15 changes: 15 additions & 0 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Maintainers

This is a community-maintained fork of `Uahh/ToastFish`.

## Maintenance Scope

- Keep the Windows version buildable and usable.
- Prioritize crash fixes, import/export reliability, notification reliability, and release packaging.
- Preserve upstream attribution and the MIT License.

## Project Boundaries

- Do not present this fork as the official upstream project unless upstream grants maintainer access or transfers ownership.
- Keep changes small and reviewable.
- Prefer issue-linked fixes over broad rewrites.
128 changes: 80 additions & 48 deletions Model/Log/CreateLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void OutputExcel(String Path, object ObjList, String Type)
else
{
// 自定义
FirstLine = new List<String> { "自定义", "第一行", "第二行", "第三行" };
FirstLine = new List<String> { "自定义", "第一行", "第二行", "第三行", "第四行" };
}
row = sheet.CreateRow(0);
for (int i = 0; i < FirstLine.Count; i++)
Expand All @@ -96,36 +96,45 @@ public object ImportExcel(string path)
List<Word> WordList = new List<Word>();
List<JpWord> JpWordList = new List<JpWord>();
List<CustomizeWord> CustWordList = new List<CustomizeWord>();
IWorkbook WorkBook;
IWorkbook WorkBook = null;
try
{
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

// Try to read WorkBook as XLSX:
try
{
WorkBook = new XSSFWorkbook(fs);
}
catch
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
WorkBook = null;
}
// Try to read WorkBook as XLSX:
try
{
WorkBook = new XSSFWorkbook(fs);
}
catch
{
WorkBook = null;
}

// If reading fails, try to read WorkBook as XLS:
if (WorkBook == null)
{
WorkBook = new HSSFWorkbook(fs);
// If reading fails, try to read WorkBook as XLS:
if (WorkBook == null)
{
fs.Position = 0;
WorkBook = new HSSFWorkbook(fs);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Excel read error", MessageBoxButton.OK, MessageBoxImage.Error);
return WordList;
return null;
}

ISheet Sheet = WorkBook.GetSheetAt(0);
if (Sheet == null)
{
MessageBox.Show("导入失败,Excel文件没有可读取的工作表");
return null;
}

IRow FirstRow = Sheet.GetRow(0);
if(FirstRow.GetCell(0).ToString() == "英语")
string importType = GetCellValue(FirstRow, 0);
if(importType == "英语")
{
int RowCount = Sheet.LastRowNum;
for (int i = 1; i <= RowCount; i++)
Expand All @@ -134,58 +143,69 @@ public object ImportExcel(string path)
Word TempWord = new Word();
if (Row == null)
continue;
TempWord.headWord = Row.GetCell(1).ToString();
TempWord.tranCN = Row.GetCell(2).ToString();
TempWord.ukPhone = Row.GetCell(3).ToString();
TempWord.usPhone = Row.GetCell(4).ToString();
TempWord.pos = Row.GetCell(5).ToString();
TempWord.phrase = Row.GetCell(6).ToString();
TempWord.phraseCN = Row.GetCell(7).ToString();
TempWord.sentence = Row.GetCell(8).ToString();
TempWord.sentenceCN = Row.GetCell(9).ToString();
TempWord.question = Row.GetCell(10).ToString();
TempWord.explain = Row.GetCell(11).ToString();
TempWord.choiceIndexOne = Row.GetCell(12).ToString();
TempWord.choiceIndexTwo = Row.GetCell(13).ToString();
TempWord.choiceIndexThree = Row.GetCell(14).ToString();
TempWord.choiceIndexFour = Row.GetCell(15).ToString();
TempWord.rightIndex = Row.GetCell(16).ToString();
TempWord.headWord = GetCellValue(Row, 1);
TempWord.tranCN = GetCellValue(Row, 2);
TempWord.ukPhone = GetCellValue(Row, 3);
TempWord.usPhone = GetCellValue(Row, 4);
TempWord.pos = GetCellValue(Row, 5);
TempWord.phrase = GetCellValue(Row, 6);
TempWord.phraseCN = GetCellValue(Row, 7);
TempWord.sentence = GetCellValue(Row, 8);
TempWord.sentenceCN = GetCellValue(Row, 9);
TempWord.question = GetCellValue(Row, 10);
TempWord.explain = GetCellValue(Row, 11);
TempWord.choiceIndexOne = GetCellValue(Row, 12);
TempWord.choiceIndexTwo = GetCellValue(Row, 13);
TempWord.choiceIndexThree = GetCellValue(Row, 14);
TempWord.choiceIndexFour = GetCellValue(Row, 15);
TempWord.rightIndex = GetCellValue(Row, 16);
if (string.IsNullOrWhiteSpace(TempWord.headWord))
continue;
WordList.Add(TempWord);
}
return WordList;
}
else if (FirstRow.GetCell(0).ToString() == "日语")
else if (importType == "日语")
{
int RowCount = Sheet.LastRowNum;
for (int i = 1; i < RowCount; i++)
for (int i = 1; i <= RowCount; i++)
{
IRow Row = Sheet.GetRow(i);
JpWord TempWord = new JpWord();
if (Row == null)
continue;
TempWord.headWord = Row.GetCell(1).ToString();
TempWord.tranCN = Row.GetCell(2).ToString();
TempWord.Phone = int.Parse(Row.GetCell(3).ToString());
TempWord.hiragana = Row.GetCell(4).ToString();
TempWord.pos = Row.GetCell(5).ToString();
TempWord.headWord = GetCellValue(Row, 1);
TempWord.tranCN = GetCellValue(Row, 2);
int phone;
TempWord.Phone = int.TryParse(GetCellValue(Row, 3), out phone) ? phone : 0;
TempWord.hiragana = GetCellValue(Row, 4);
TempWord.pos = GetCellValue(Row, 5);
if (string.IsNullOrWhiteSpace(TempWord.headWord))
continue;
JpWordList.Add(TempWord);
}
return JpWordList;
}
else if (FirstRow.GetCell(0).ToString() == "自定义")
else if (importType == "自定义")
{
int RowCount = Sheet.LastRowNum;
int CellCount = FirstRow.LastCellNum;
for (int i = 1; i < RowCount; i++)
for (int i = 1; i <= RowCount; i++)
{
IRow Row = Sheet.GetRow(i);
CustomizeWord TempWord = new CustomizeWord();
if (Row == null)
continue;
TempWord.firstLine = Row.GetCell(1).ToString();
TempWord.secondLine = Row.GetCell(2).ToString();
TempWord.thirdLine = Row.GetCell(3).ToString();
TempWord.fourthLine = Row.GetCell(4).ToString();
TempWord.firstLine = GetCellValue(Row, 1);
TempWord.secondLine = GetCellValue(Row, 2);
TempWord.thirdLine = GetCellValue(Row, 3);
TempWord.fourthLine = GetCellValue(Row, 4);
if (string.IsNullOrWhiteSpace(TempWord.firstLine)
&& string.IsNullOrWhiteSpace(TempWord.secondLine)
&& string.IsNullOrWhiteSpace(TempWord.thirdLine)
&& string.IsNullOrWhiteSpace(TempWord.fourthLine))
{
continue;
}
CustWordList.Add(TempWord);
}
return CustWordList;
Expand All @@ -196,5 +216,17 @@ public object ImportExcel(string path)
return null;
}
}

private string GetCellValue(IRow row, int cellIndex)
{
if (row == null)
return string.Empty;

ICell cell = row.GetCell(cellIndex);
if (cell == null)
return string.Empty;

return cell.ToString().Trim();
}
}
}
Loading
Loading