Implement just in readMode View.

This commit is contained in:
fastrick 2025-04-13 18:06:21 +00:00
parent 7919245b6c
commit 5c6b92cd49
3 changed files with 195 additions and 11 deletions

7
.gitignore vendored
View file

@ -25,6 +25,10 @@ data.json
# Exclude macOS Finder (System Explorer) View States
.DS_Store
styles.css
package-lock.json
# cursorrules
.cursorrules
@ -33,4 +37,5 @@ data.json
# translations
scripts
translation-templates
translation-templates
._data.json

View file

@ -15,6 +15,7 @@ import { RegExpCursor } from "./regexp-cursor";
import TaskProgressBarPlugin, { showPopoverWithProgressBar } from "..";
import { shouldHideProgressBarInLivePriview } from "../utils";
import "../styles/progressbar.css";
import { TaskGoalManager } from "src/utils/goal/main";
interface Tasks {
completed: number;
@ -702,6 +703,10 @@ export function taskProgressBarExtension(
line.from,
line.to
);
// Extract the task text and check for goal information
const customGoal = TaskGoalManager.extractTaskAndGoalInfo(lineText);
if (
!lineText ||
!/^[\s|\t]*([-*+]|\d+\.)\s\[(.)\]/.test(lineText)
@ -724,9 +729,10 @@ export function taskProgressBarExtension(
if (!rangeText || rangeText.length === 1) continue;
const tasksNum = this.extractTasksFromRange(
range,
range,
view.state,
true
true,
customGoal // Add custom goal to the task count
);
if (tasksNum.total === 0) continue;
@ -840,14 +846,15 @@ export function taskProgressBarExtension(
private extractTasksFromRange(
range: TextRange,
state: EditorState,
isBullet: boolean
isBullet: boolean,
customGoal?: number | null
): Tasks {
const textArray = this.getDocumentTextArray(
state.doc,
range.from,
range.to
);
return this.calculateTasksNum(textArray, isBullet);
return this.calculateTasksNum(textArray, isBullet, customGoal);
}
/**
@ -1275,7 +1282,8 @@ export function taskProgressBarExtension(
public calculateTasksNum(
textArray: string[],
bullet: boolean
bullet: boolean,
customGoal?: number | null
): Tasks {
if (!textArray || textArray.length === 0) {
return {
@ -1315,7 +1323,9 @@ export function taskProgressBarExtension(
let planned: number = 0;
let total: number = 0;
let level: number = 0;
let completedGoalValue: number = 0;
let totalGoalValue: number = 0;
// Get tab size from vault config
const tabSize = this.getTabSize();
@ -1324,6 +1334,7 @@ export function taskProgressBarExtension(
mark: string;
status: string;
lineText: string;
goalValue?: number;
}[] = [];
// Determine indentation level for bullets
@ -1374,6 +1385,24 @@ export function taskProgressBarExtension(
// Get the task status
const status = this.getTaskStatus(lineTextTrimmed);
// Extract task text to check for task-specific goal
const taskText = TaskGoalManager.extractTaskText(lineTextTrimmed);
let taskGoalValue = 0;
if (taskText) {
// Check for task-specific goal
const taskGoal = TaskGoalManager.extractTaskSpecificGoal(taskText);
if (taskGoal !== null) {
taskGoalValue = taskGoal;
totalGoalValue += taskGoalValue;
// If task is completed, add its goal value to completedGoalValue
if (status === "completed") {
completedGoalValue += taskGoalValue;
}
}
}
// Extract the mark for debugging
const markMatch = lineTextTrimmed.match(/\[(.)]/);
if (markMatch && markMatch[1]) {
@ -1381,6 +1410,7 @@ export function taskProgressBarExtension(
mark: markMatch[1],
status: status,
lineText: lineTextTrimmed,
goalValue: taskGoalValue > 0 ? taskGoalValue : undefined
});
}
@ -1450,7 +1480,7 @@ export function taskProgressBarExtension(
}
}
// Ensure counts don't exceed total
// Ensure counts don't exceed total
completed = Math.min(completed, total);
inProgress = Math.min(inProgress, total - completed);
abandoned = Math.min(abandoned, total - completed - inProgress);
@ -1460,15 +1490,26 @@ export function taskProgressBarExtension(
);
notStarted =
total - completed - inProgress - abandoned - planned;
return {
// Use the TaskGoalManager to adjust counts based on goals
const taskCounts = {
completed,
total,
inProgress,
abandoned,
notStarted,
planned,
planned
};
// Apply goal-based adjustments using the TaskGoalManager
const adjustedCounts = TaskGoalManager.adjustTaskCountsForGoals(
taskCounts,
customGoal ? customGoal : null,
completedGoalValue,
totalGoalValue
);
return adjustedCounts;
}
},
{

138
src/utils/goal/main.ts Normal file
View file

@ -0,0 +1,138 @@
/**
* Goal Tracking System
*
* This module handles goal-related functionality for tasks in Obsidian Task Genius.
* It supports extracting goal information from task text using g::number and goal::number formats.
*/
/**
* Represents a collection of task-specific goal values
*/
export interface TaskGoalValues {
/** Sum of goal values from completed tasks */
completedGoalValue: number;
/** Sum of all goal values from tasks */
totalGoalValue: number;
}
/**
* Class that manages all goal-related functionality
*/
export class TaskGoalManager {
/**
* Extract the text content of a task from a markdown line
*
* @param lineText The full text of the markdown line containing the task
* @return The extracted task text or null if no task was found
*/
static extractTaskText(lineText: string): string | null {
if (!lineText) return null;
const taskTextMatch = lineText.match(/^[\s|\t]*([-*+]|\d+\.)\s\[(.)\]\s*(.*?)$/);
if (taskTextMatch && taskTextMatch[3]) {
return taskTextMatch[3].trim();
}
return null;
}
static isGoalActive(taskText: string): boolean {
if (!taskText) return false;
// Check for the presence of g:: or goal:: in the task text
const goalMatch = taskText.match(/\b(g|goal)::(\d+)\b/i);
return !!goalMatch;
}
/**
* Extract the goal value from a task text
* Supports only g::number or goal::number format
*
* @param taskText The task text to extract the goal from
* @return The extracted goal value or null if no goal found
*/
static extractTaskSpecificGoal(taskText: string): number | null {
if (!taskText) return null;
// Match only the patterns g::number or goal::number
const goalMatch = taskText.match(/\b(g|goal)::(\d+)\b/i);
if (!goalMatch) return null;
return Number(goalMatch[2]);
}
/**
* Extract task text and goal information from a line
*
* @param lineText The full text of the markdown line containing the task
* @return The extracted goal value or null if no goal found
*/
static extractTaskAndGoalInfo(lineText: string | null): number | null {
if (!lineText) return null;
// Extract task text
const taskText = TaskGoalManager.extractTaskText(lineText);
if (!taskText) return null;
// Check for goal in g::number or goal::number format
return TaskGoalManager.extractTaskSpecificGoal(taskText);
}
/**
* Adjust task counts based on goal values
*
* @param taskCounts Current task count values
* @param customGoal Custom goal total value
* @param completedGoalValue Sum of goal values from completed tasks
* @param totalGoalValue Sum of all goal values
* @return Updated task counts with goal-based adjustments
*/
static adjustTaskCountsForGoals(
taskCounts: {
completed: number;
total: number;
inProgress?: number;
abandoned?: number;
notStarted?: number;
planned?: number;
},
customGoal: number | null,
completedGoalValue: number,
totalGoalValue: number
) {
const { completed, total, inProgress = 0, abandoned = 0, planned = 0 } = taskCounts;
let adjustedCounts = { ...taskCounts };
// If we have a custom goal specified with g::number format, use it as the total
if (customGoal !== null) {
// Always set the total to be the custom goal when specified
adjustedCounts.total = customGoal;
// If we also have task-specific goals, use the goal values to calculate completion
if (totalGoalValue > 0) {
// Calculate the percentage of completion based on goal values
const completionRatio = completedGoalValue / customGoal;
console.log("Completion ratio:", completionRatio);
console.log("Custom goal:", customGoal);
// Calculate completed count based on the goal completion ratio
adjustedCounts.completed = Math.round(completionRatio * customGoal);
adjustedCounts.completed = Math.min(adjustedCounts.completed, customGoal); // Ensure it doesn't exceed total
// Adjust other counts proportionally
adjustedCounts.notStarted = customGoal - adjustedCounts.completed - inProgress - abandoned - (planned || 0);
adjustedCounts.notStarted = Math.max(0, adjustedCounts.notStarted); // Ensure it's not negative
} else {
// If no task-specific goals, use the completed tasks against the custom total goal
adjustedCounts.completed = Math.min(completed, customGoal);
// Adjust notStarted to make the math work out with the new total
adjustedCounts.notStarted = customGoal - adjustedCounts.completed - inProgress - abandoned - (planned || 0);
adjustedCounts.notStarted = Math.max(0, adjustedCounts.notStarted);
}
}
console.log("Adjusted task counts for goals:", adjustedCounts);
return adjustedCounts;
}
}