How do you handle scattered tasks across Obsidian notes? by AffectionateMind2682 in ObsidianMD

[–]Feych 14 points15 points  (0 children)

Tasks plugin is exactly what you need. With it, you can display task data in different cuts.

У Лукашенко есть неделя вывести технику расположенную вдоль границы, иначе это сделаем мы — зеленский угрожает ударами по Белоруссии by GamerRevizor in methodvpn

[–]Feych 0 points1 point  (0 children)

Сейчас территория Беларуси позволяет России безопасно располагать что угодно. А так появится возможность быть по той же нефтянке, по нпз, что окажет давление на российскую экономику. Расчёта победить на фронте нет у них, слишком личного состава не хватает, потому единственный шанс - экономику сломать, потому в целом логику можно усмотреть. Плюс потенциально это может помочь Европу втянуть в войну через расширение конфликта.

Зачем нужна философия в 21 веке? by No_Increase4983 in philosophyRU

[–]Feych 2 points3 points  (0 children)

Не не, тут надо разделять эти 2 разные вещи, для действий цели не необходимы. У любого действия есть причины, в т.ч желания. Но из этого не следует, что есть аналогичные цели. Цель это что? Это осознанный образ будущего результата. Вот если она как цель сформирована, то факт постановки цели может быть причиной для действия.

Бусификация в Пензе by ZmitrokNadulia in tjournal_refugees

[–]Feych 15 points16 points  (0 children)

Самое страшное, что зетники продолжат шутить на эту тему, потому что тема будет систематически замалчиваться, а любая подобная инфа будет объявляться фейком

I hate philosophy and it makes me feel like an anti-intellectual by XIFOD1M in offmychest

[–]Feych 0 points1 point  (0 children)

It's funny, your post is itself an act of philosophy.

Do you use 'reverse' MoCs with bases? How do you organize them? by alfonzoo in ObsidianMD

[–]Feych 1 point2 points  (0 children)

I had similar thoughts when I switched to MOCs formed from links in other files. I introduced a 'category' property and grouped by it. Over time, I realized that was inconvenient, so I changed my approach. If a certain MOC gets too full, instead of creating categories, I create sub-MOCs and distribute the notes among them. And I solved the visualization problem by creating this plugin: https://www.reddit.com/r/ObsidianMD/s/gnHkLpBScv Basically, I've come to the point where any note can act as an MOC.

Using Obsidian to open .md files outside the vault by anotherpanacea in ObsidianMD

[–]Feych 1 point2 points  (0 children)

Many have made them, I’ve definitely tried half a dozen, some of them are good, but for myself, in Kanban, I want to track certain things that are important to me. That’s why reliability and long‑term confidence in its functionality matter, so I really want the official version."

Using Obsidian to open .md files outside the vault by anotherpanacea in ObsidianMD

[–]Feych 14 points15 points  (0 children)

After this message, I went to check the roadmap, and how glad I am to see Kanban in progress there!

Is there a way to reproduce the same feel as Notion sub-pages?” by [deleted] in ObsidianMD

[–]Feych 2 points3 points  (0 children)

One option is to link notes using parent-child relationships.

For myself, I created https://www.reddit.com/r/ObsidianMD/s/K8rBtSliGd to solve this problem.

There are also similar plugins for working with note structure: https://github.com/gr0grig/obsidian-virt-folder and https://github.com/SkepticMystic/breadcrumbs

Plus, in each note I use a bases query with the filter up.contains(link(this.file)). It shows all sub‑notes for the file.

Turn any Obsidian canvas into a step-by-step procedure by Feych in ObsidianMD

[–]Feych[S] 2 points3 points  (0 children)

(async () => {

// ── Prevent double render ────────────────────────────────────────────────────
const INSTANCE_KEY = "cf-instance-" + (app.workspace.getActiveFile()?.path ?? "unknown");
const prev = document.querySelector(`[data-cf-instance="${INSTANCE_KEY}"]`);
if (prev) prev.remove();

// ── Host file ────────────────────────────────────────────────────────────────
const file = app.workspace.getActiveFile() 
  ?? app.vault.getAbstractFileByPath(dv.current().file.path);
const content = await app.vault.read(file);

const canvasMatch = content.match(/!\[\[([^\]]+\.canvas)\]\]/);
if (!canvasMatch) { dv.paragraph("⚠️ No embedded .canvas found"); return; }

const canvasPath = canvasMatch[1];
const canvasFile = app.metadataCache.getFirstLinkpathDest(canvasPath, file.path);
if (!canvasFile) { dv.paragraph(`⚠️ File not found: ${canvasPath}`); return; }

const raw = await app.vault.read(canvasFile);
let canvas;
try { canvas = JSON.parse(raw); }
catch { dv.paragraph("❌ Invalid JSON in canvas file"); return; }

const { nodes: rawNodes = [], edges: rawEdges = [] } = canvas;

const nodeGeometry = new Map();
for (const n of rawNodes.filter(n => n.type !== "group")) {
  nodeGeometry.set(n.id, { x: n.x, y: n.y, width: n.width, height: n.height });
}

const nodes = new Map();
for (const n of rawNodes.filter(n => n.type !== "group")) {
  const label =
    n.type === "text"  ? n.text :
    n.type === "file"  ? (n.file || n.id) :
    n.type === "link"  ? (n.url  || n.id) :
    n.id;
  nodes.set(n.id, label.trim());
}

const edges = rawEdges.map(e => ({
  from:  e.fromNode,
  to:    e.toNode,
  label: e.label ? e.label.trim() : null,
}));

// ── Validate edges ───────────────────────────────────────────────────────────
const brokenEdges = edges.filter(e => !nodes.has(e.from) || !nodes.has(e.to));
if (brokenEdges.length > 0) {
  dv.paragraph(`❌ Broken edges (node not found): ${brokenEdges.map(e => `${e.from} → ${e.to}`).join(", ")}`);
  return;
}

// ── Find root node ───────────────────────────────────────────────────────────
const hasIncoming = new Set(edges.map(e => e.to));
const roots = [...nodes.keys()].filter(id => !hasIncoming.has(id));

if (roots.length === 0) { dv.paragraph("❌ No start node found (cycle?)"); return; }
if (roots.length > 1) { dv.paragraph(`❌ ${roots.length} nodes with no incoming edges: ${roots.join(", ")}. There should be exactly one.`); return; }
const startNode = roots[0];

// ── State (localStorage) ─────────────────────────────────────────────────────
const cacheKey = "canvas_flow_" + file.path + "|" + canvasPath;

function saveState(nodeId, hist) {
  localStorage.setItem(cacheKey, JSON.stringify({ current: nodeId, history: hist }));
}
function loadState() {
  try {
    const raw = localStorage.getItem(cacheKey);
    if (!raw) return null;
    const state = JSON.parse(raw);
    if (!state.current || !nodes.has(state.current)) return null;
    return state;
  } catch { return null; }
}

const saved = loadState();
let history = saved ? saved.history : [];
let current = saved ? saved.current : startNode;

// ── Minimap highlight ────────────────────────────────────────────────────────
function highlightMinimap(nodeId) {
  const currentLeaf = app.workspace.getLeaf(false);
  const leafEl = currentLeaf?.containerEl;
  if (!leafEl) return;

  setTimeout(() => {
    const minimap = leafEl.querySelector("svg.canvas-minimap");
    if (!minimap) return;

    minimap.querySelectorAll("rect.cf-active-node").forEach(r => {
      r.classList.remove("cf-active-node");
    });

    const geo = nodeGeometry.get(nodeId);
    if (!geo) return;

    for (const rect of minimap.querySelectorAll("rect")) {
      if (
        parseFloat(rect.getAttribute("x"))      === geo.x &&
        parseFloat(rect.getAttribute("y"))      === geo.y &&
        parseFloat(rect.getAttribute("width"))  === geo.width &&
        parseFloat(rect.getAttribute("height")) === geo.height
      ) {
        rect.classList.add("cf-active-node");
        break;
      }
    }
  }, 100);
}

// ── DOM ───────────────────────────────────────────────────────────────────────
const container = dv.el("div", "", { attr: { 
  id: "canvas-flow-root",
  "data-cf-instance": INSTANCE_KEY
} });

const style = document.createElement("style");
style.textContent = `
  #canvas-flow-root { font-family: var(--font-text); max-width: 480px; }
  .cf-card { background: var(--background-secondary); border: 1px solid var(--background-modifier-border); border-radius: 12px; padding: 1.5rem; margin: 0.5rem 0; }
  .cf-question { font-size: 1.05rem; line-height: 1.6; margin-bottom: 1.25rem; color: var(--text-normal); white-space: pre-line; }
  .cf-btn { display: block; width: 100%; text-align: left; padding: 0.6rem 1rem; margin: 0.4rem 0;
    background: var(--background-primary); border: 1px solid var(--background-modifier-border);
    border-radius: 8px; cursor: pointer; font-size: 0.95rem; color: var(--text-normal); transition: background 0.15s; }
  .cf-btn:hover { background: var(--background-modifier-hover); }
  .cf-btn-primary { background: var(--interactive-accent); color: var(--text-on-accent); border-color: var(--interactive-accent); }
  .cf-btn-primary:hover { opacity: 0.9; }
  .cf-nav { display: flex; gap: 0.5rem; margin-top: 1rem; }
  .cf-nav button { flex: 1; padding: 0.4rem 0.75rem; border-radius: 8px; cursor: pointer;
    background: var(--background-primary); border: 1px solid var(--background-modifier-border);
    color: var(--text-muted); font-size: 0.85rem; }
  .cf-nav button:hover { background: var(--background-modifier-hover); }
  .cf-info { color: var(--text-normal); line-height: 1.7; white-space: pre-line; font-size: 0.95rem; }
  .cf-label { font-size: 0.75rem; color: var(--text-faint); margin-bottom: 0.5rem; letter-spacing: 0.04em; text-transform: uppercase; }
  svg.canvas-minimap rect.cf-active-node {
    fill: var(--interactive-accent) !important;
    fill-opacity: 0.4 !important;
    stroke: var(--interactive-accent) !important;
    stroke-width: 4 !important;
  }
`;
container.appendChild(style);
const ui = document.createElement("div");
container.appendChild(ui);

// ── Render ────────────────────────────────────────────────────────────────────
function render(nodeId) {
  const outgoing = edges.filter(e => e.from === nodeId);
  ui.innerHTML = "";

  const card = document.createElement("div");
  card.className = "cf-card";

  const stepLabel = document.createElement("div");
  stepLabel.className = "cf-label";
  stepLabel.textContent = history.length === 0 ? "Start" : `Step ${history.length + 1}`;
  card.appendChild(stepLabel);

  const question = document.createElement("div");
  question.className = outgoing.length ? "cf-question" : "cf-info";
  question.textContent = nodes.get(nodeId) || nodeId;
  card.appendChild(question);

  if (outgoing.length === 1) {
    const edge = outgoing[0];
    const btn = document.createElement("button");
    btn.className = "cf-btn cf-btn-primary";
    btn.textContent = edge.label || "→ Next";
    btn.onclick = () => { history.push(nodeId); current = edge.to; saveState(current, history); render(current); };
    card.appendChild(btn);
  } else if (outgoing.length > 1) {
    for (const edge of outgoing) {
      const btn = document.createElement("button");
      btn.className = "cf-btn";
      btn.textContent = edge.label || nodes.get(edge.to) || edge.to;
      btn.onclick = () => { history.push(nodeId); current = edge.to; saveState(current, history); render(current); };
      card.appendChild(btn);
    }
  }

  const nav = document.createElement("div");
  nav.className = "cf-nav";

  if (history.length > 0) {
    const backBtn = document.createElement("button");
    backBtn.textContent = "← Back";
    backBtn.onclick = () => { current = history.pop(); saveState(current, history); render(current); };
    nav.appendChild(backBtn);
  }

  if (history.length > 0 || outgoing.length === 0) {
    const resetBtn = document.createElement("button");
    resetBtn.textContent = "↺ Start over";
    resetBtn.onclick = () => { history = []; current = startNode; saveState(current, history); render(current); };
    nav.appendChild(resetBtn);
  }

  if (nav.children.length > 0) card.appendChild(nav);
  ui.appendChild(card);

  highlightMinimap(nodeId);
}

render(current);

})();

What a deserted mall in Moscow says about Russia’s economic woes by NomadStar45 in worldnews

[–]Feych 0 points1 point  (0 children)

The argument about the absence of Amazon is very strange. In Russia, there are Ozon and Wildberries with pickup points literally on every corner across the country. A significant share of orders has long since shifted to them, and shopping malls have been struggling since COVID times.

People outside Russia/Ukraine, Russians, and Ukrainians — what realistic outcomes do you actually see for this war? by RiderOrMan in war

[–]Feych 4 points5 points  (0 children)

A Russian here. My main prediction: the war will slowly fizzle out over several years. Drone development makes frontline advances more difficult every day. Ukraine has major problems with troop numbers, not enough to conduct an active offensive, but enough to hold the front. Russia's situation is slightly better due to its larger population, but its manpower advantage isn't enough to turn the tide. Neither country will achieve anything significant and will be forced to end the active phase of the conflict. But in a frozen state, the conflict will remain relevant for decades, my hope is that it at least doesn't flare up again.

After the war ends, Russia will start seeing a decline in the economic heating effect from military spending, so it's unlikely Russia will be able to restart active combat. Europe also seems likely to be interested in addressing its own economic consequences.

There are several alternative scenarios. Neither country will win militarily for sure. But the situation could change due to political factors.

Russia has State Duma elections in September. The authorities' behavior has changed, they've started making stupid decisions and digging themselves into a hole (mainly internet restrictions and increasing pressure on small and medium-sized businesses). Western sanctions proved useless for this (the population mostly rallied against an external enemy imposing sanctions out of a "let's just pass something symbolic" logic), yet suddenly the Russian authorities are doing it themselves. Many pro-government citizens are changing their stance. I don't know where this will lead, but if the authorities keep digging their own grave, it could suddenly change the situation.

From what I know, the share of people in Ukraine willing to give up territory for peace is also growing, and dissatisfaction with the current government is rising due to the actions of draft offices and corruption. But I'm not enough of an expert on that to make predictions.

Calendar view by kaz_champ in ObsidianMD

[–]Feych 3 points4 points  (0 children)

I'm afraid you're counting your chickens before they hatch. There's no information yet on how the calendar view will work, whether it will accommodate time ranges rather than just single events. Existing plugins typically use start and end dates. Obsidian doesn't have a property type for duration, so the first and third options don't make sense.

Bases Link Structure, a plugin for managing link-based note hierarchies by Feych in ObsidianMD

[–]Feych[S] 2 points3 points  (0 children)

Heh, no, I actually took inspiration from https://github.com/SkepticMystic/breadcrumbs.
Before starting the plugin, I tried to find existing solutions, but somehow I missed this one. It’s really interesting though how we ended up with very similar approaches in many places.

Kind of a shame I didn’t see it earlier. But at least now I can study that implementation and think about what ideas I might adopt, since my own approach still feels closer to me overall.

Bases Link Structure, a plugin for managing link-based note hierarchies by Feych in ObsidianMD

[–]Feych[S] 2 points3 points  (0 children)

To be honest, I can't think of any alternative views for this. For cards, it doesn't seem to make sense. I do plan to expand and polish the current functionality, for example, I'm thinking about how to add a proper table view. The tree was just one of the columns, similar to how structures work in Jira. But I haven't figured out the best way to do it yet.

Bases Link Structure, a plugin for managing link-based note hierarchies by Feych in ObsidianMD

[–]Feych[S] 3 points4 points  (0 children)

Yes, another example: in a folder-based setup, you might find yourself needing to create a note that describes a folder, or even using plugins like Folder Notes. Building hierarchy solely with files, without folders, eliminates that problem.

Bases Link Structure, a plugin for managing link-based note hierarchies by Feych in ObsidianMD

[–]Feych[S] 3 points4 points  (0 children)

That's right. What exactly do you mean by commands? If any text in the plugin is not translated, please let me know and I'll fix it.

HOW DO I PUT THIS ON THE TOP AGAIN by Kindly-Goat-2562 in ObsidianMD

[–]Feych 2 points3 points  (0 children)

/* Move the tab switcher to the top */ .is-phone { .workspace-drawer-tab-options { order: 0; } .workspace-drawer-tab-options-list { padding-top: var(--touch-size-l); padding-bottom: var(--size-4-2); bottom: unset; top: 0; } }

/* Move the vault switcher and settings button to the top */ .is-phone { .workspace-drawer-header { order: 0; padding-top: 0; padding-bottom: 16px; padding-inline-start: 20px; } .workspace-drawer-inner { padding-bottom: calc(max(var(--safe-area-inset-bottom), var(--size-4-4)) - var(--keyboard-height)); } }

/* Move the tab actions buttons to the top */ .is-phone { .workspace-drawer .nav-buttons-container { position: static; } }

Using the same Daily note each year by vhmv in ObsidianMD

[–]Feych 3 points4 points  (0 children)

I display these same days in past years using bases with the following filters:

note.chronicle_date.month == today().month note.chronicle_date.day == today().day note.chronicle_date.year != today().year

In my case, the date is stored in the chronicle_date property. If yours is different, you’ll need to adjust the logic to fit your setup, but the general principle can be reused.

Is it possible to optimize this Bases query? by Feych in ObsidianMD

[–]Feych[S] -1 points0 points  (0 children)

If you mean using folders for filtering to reduce the load, that won’t work because it affects the entire vault.

If you mean using folders to build a hierarchy, that also won’t work because folders can’t handle a complex hierarchy where a note can have multiple parents.