Skip to content
Merged
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
54 changes: 54 additions & 0 deletions src/ts/contentScripts/estimates/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {Roam, RoamNode} from '../../utils/roam';
import {Feature, Settings, Shortcut, String} from '../../utils/settings';
import {getActiveEditElement} from '../../utils/dom';

const estimateProperty: String = {type: 'string', id: 'estimate_property', label: 'Property to base estimates on'};

export const config: Feature = {
id: 'calculate-estimate',
name: 'Calculate estimate',
settings: [
{
type: 'shortcut',
id: 'calculate-estimate',
label: 'Calculate estimate shortcut',
initValue: 'ctrl+m',
placeholder: '',
onPress: calculateFirstSiblingTotal
} as Shortcut,
estimateProperty,
],
};

function getParentElement() {
return getActiveEditElement()?.closest('.roam-block-container')?.parentElement;
}

/** I'm still figuring out UX on this one.
* The current expectation is that you have to create a parent node, put a query as a child of it,
* then run this with cursor ina query sibling.
* Maybe I should create sibling? then you can do it from query node, which seems somewhat more intuitive
* but when your cursor is in the query node it's not rendered, which may be confusing
*
* or maybe flow - you select query node, then press shortcut, get estimate for it in new node below
*
*/
export async function calculateFirstSiblingTotal() {
const attributeName = await Settings.get(config.id, estimateProperty.id, 'pomodoro_estimate');
const estimateRegex = new RegExp(`${attributeName}:\\s*(\\d+\\.?\\d*)`, 'g');

const queryNode = getParentElement()?.querySelector('.rm-reference-main') as HTMLElement;
const queryText = queryNode?.innerText;
console.log('Extracting estimate from ' + queryText);

let total = 0;

const nextMatch = () => estimateRegex.exec(queryText);
let match = nextMatch();
while (match) {
total += parseFloat(match[1]);
match = nextMatch();
}

Roam.applyToCurrent(node => new RoamNode(`total_${attributeName}::${total}` + node.text, node.selection))
}
2 changes: 2 additions & 0 deletions src/ts/contentScripts/features.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {config as incDec} from './inc-dec-value/index'
import {config as customCss} from './custom-css/index'
import {config as srs} from './srs/index'
import {config as blockManipulation} from './block-manipulation'
import {config as estimate} from './estimates/index'
import {filterAsync, mapAsync} from '../utils/async';

export const Features = {
Expand All @@ -12,6 +13,7 @@ export const Features = {
customCss,
srs,
blockManipulation,
estimate,
]),

isActive: Settings.isActive,
Expand Down
3 changes: 2 additions & 1 deletion src/ts/utils/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ export interface Shortcut extends Setting {


export const Settings = {
get: async (featureId: string, settingId: string) => (await getStateFromStorage())[featureId][settingId],
get: async (featureId: string, settingId: string, defaultValue?: string) =>
(await getStateFromStorage())[featureId][settingId] || defaultValue,
isActive: async (featureId: string) => (await getStateFromStorage())[featureId]?.active
}

Expand Down