chore: rename to chessStudy

This commit is contained in:
chrislicodes 2023-05-18 14:43:46 +02:00
parent 613d09480d
commit 4638ea7855
14 changed files with 97 additions and 96 deletions

View file

@ -1,6 +1,6 @@
<!-- omit in toc -->
# Chessify
# Obsidian Chess Study
> A chess study helper and PGN viewer/editor for [Obsidian](https://obsidian.md/).
@ -26,23 +26,23 @@ I love [Obsidian](https://obsidian.md/) and its tools, but managing screenshots
## Installation
Once you have disabled Safe Mode, you can find third-party plugins by navigating to Settings > Community Plugins > Browse and search for "Chessify". Once you have installed the plugin, you can access it under Settings > Community Plugins. Please note that you must enable the plugin to use it. You can also unsintall the plugin from there.
Once you have disabled Safe Mode, you can find third-party plugins by navigating to Settings > Community Plugins > Browse and search for "Chess Study". Once you have installed the plugin, you can access it under Settings > Community Plugins. Please note that you must enable the plugin to use it. You can also unsintall the plugin from there.
## Usage
To start, position your cursor where you want to place the PGN viewer/editor within your note. Execute the Obsidian command `Chessify: Insert PGN-Editor at cursor position`.
To start, position your cursor where you want to place the PGN viewer/editor within your note. Execute the Obsidian command `Chess Study: Insert PGN-Editor at cursor position`.
This action will trigger a modal window, where you have the option to paste your PGN or leave it empty for a fresh new game. Here is what it will look like:
![chessify-modal](imgs/chessify-modal.png)
![chess-study-modal](imgs/chess-study-modal.png)
Once you click `Submit`, Chessify will parse the PGN, generate a new JSON file in your vault located at `.obsidian/plugins/obsidian-chessify/storage/{id}.json`, and insert a chessify codeblock at the cursor's position. Here's an example of the chessify codeblock:
Once you click `Submit`, Obsidian will parse the PGN, generate a new JSON file in your vault located at `.obsidian/plugins/obsidian-chess-study/storage/{id}.json`, and insert a chessStudy codeblock at the cursor's position. Here's an example of the chessStudy codeblock:
![chessify-codeblock](imgs/chessify-codeblock.png)
![chess-study-codeblock](imgs/chess-study-codeblock.png)
After that the PGN viewer/editor will render and you are good to go:
![chessify-codeblock](imgs/chessify-demo.gif)
![cchess-study-codeblock](imgs/chess-study-demo.gif)
## Features
@ -56,15 +56,15 @@ After that the PGN viewer/editor will render and you are good to go:
## Settings
Here are the available settings for a `chessify` code block:
Here are the available settings for a `chessStudy` code block:
| Setting | Possible Values | Description |
| ------------------ | ------------------ | ------------------------------------------------ |
| `chessifyId` | Valid nanoid | Valid ID for a file stored in the plugin storage |
| `chessStudyId` | Valid nanoid | Valid ID for a file stored in the plugin storage |
| `boardOrientation` | `white` \| `black` | Orientation of the board |
| `boardColor` | `green` \| `brown` | Color of the board |
You can permanently set some settings in the [Obsidian](https://obsidian.md/) plugin settings for Chessify.
You can permanently set some settings in the [Obsidian](https://obsidian.md/) plugin settings for Obsidian Chess Study.
## Roadmap
@ -91,4 +91,4 @@ If you want to have a look at FENs instead, check out these alternative Obsidian
## License
[Chessify](https://github.com/chrislicodes/obsidian-chessify) is licensed under the MIT license. Refer to [LICENSE](https://github.com/chrislicodes/obsidian-chessify/blob/trunk/LICENSE.TXT) for more informations.
[Obsidian Chess Study](https://github.com/chrislicodes/obsidian-chess-study) is licensed under the GPL-3.0 license. Refer to [LICENSE](https://github.com/chrislicodes/obsidian-chess-study/blob/trunk/LICENSE.TXT) for more informations.

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -1,6 +1,6 @@
{
"id": "chessify",
"name": "Chessify",
"id": "chess-study",
"name": "Chess Study",
"version": "1.0.0",
"minAppVersion": "0.15.0",
"description": "A chess study helper and PGN viewer for Obsidian.",

6
package-lock.json generated
View file

@ -1,13 +1,13 @@
{
"name": "obsidian-chessify",
"name": "chess-study",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "obsidian-chessify",
"name": "chess-study",
"version": "1.0.0",
"license": "MIT",
"license": "GPL-3.0-or-later",
"dependencies": {
"@tiptap/pm": "2.0.3",
"@tiptap/react": "2.0.3",

View file

@ -1,12 +1,12 @@
{
"name": "obsidian-chessify",
"name": "chess-study",
"version": "1.0.0",
"description": "A chess study helper and PGN viewer for Obsidian.",
"keywords": [
"chess",
"obsidian"
],
"license": "MIT",
"license": "GPL-3.0-or-later",
"author": "Christoph Lindstädt",
"main": "main.js",
"scripts": {

View file

@ -1,25 +1,25 @@
import { App, MarkdownRenderChild } from 'obsidian';
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import { ChessifyDataAdapter, ChessifyFileData } from 'src/utils';
import { Chessify } from '../components/react/Chessify';
import { ChessifyPluginSettings } from './obsidian/SettingsTab';
import { ChessStudyDataAdapter, ChessStudyFileData } from 'src/utils';
import { ChessStudyPluginSettings } from './obsidian/SettingsTab';
import { ChessStudy } from './react/ChessStudy';
export class ReactView extends MarkdownRenderChild {
root: ReactDOM.Root;
source: string;
app: App;
settings: ChessifyPluginSettings;
data: ChessifyFileData;
dataAdapter: ChessifyDataAdapter;
settings: ChessStudyPluginSettings;
data: ChessStudyFileData;
dataAdapter: ChessStudyDataAdapter;
constructor(
containerEL: HTMLElement,
source: string,
app: App,
settings: ChessifyPluginSettings,
data: ChessifyFileData,
dataAdapter: ChessifyDataAdapter
settings: ChessStudyPluginSettings,
data: ChessStudyFileData,
dataAdapter: ChessStudyDataAdapter
) {
super(containerEL);
this.source = source;
@ -33,11 +33,11 @@ export class ReactView extends MarkdownRenderChild {
this.root = ReactDOM.createRoot(this.containerEl);
this.root.render(
<React.StrictMode>
<Chessify
<ChessStudy
source={this.source}
app={this.app}
pluginSettings={this.settings}
chessifyData={this.data}
chessStudyData={this.data}
dataAdapter={this.dataAdapter}
/>
</React.StrictMode>

View file

@ -1,20 +1,20 @@
import { App, PluginSettingTab, Setting } from 'obsidian';
import ChessifyPlugin from 'src/main';
import ChessStudyPlugin from 'src/main';
export interface ChessifyPluginSettings {
export interface ChessStudyPluginSettings {
boardOrientation: 'white' | 'black';
boardColor: 'green' | 'brown';
}
export const DEFAULT_SETTINGS: ChessifyPluginSettings = {
export const DEFAULT_SETTINGS: ChessStudyPluginSettings = {
boardOrientation: 'white',
boardColor: 'green',
};
export class SettingsTab extends PluginSettingTab {
plugin: ChessifyPlugin;
plugin: ChessStudyPlugin;
constructor(app: App, plugin: ChessifyPlugin) {
constructor(app: App, plugin: ChessStudyPlugin) {
super(app, plugin);
this.plugin = plugin;
}
@ -24,7 +24,7 @@ export class SettingsTab extends PluginSettingTab {
containerEl.empty();
containerEl.createEl('h2', { text: 'Obsidian Chessify Settings' });
containerEl.createEl('h2', { text: 'Obsidian Chess Study Settings' });
new Setting(containerEl)
.setName('Board Orientation')

View file

@ -5,46 +5,46 @@ import { DrawShape } from 'chessground/draw';
import { App, Notice } from 'obsidian';
import * as React from 'react';
import { useCallback, useMemo, useState } from 'react';
import { ChessifyPluginSettings } from 'src/components/obsidian/SettingsTab';
import { ChessStudyPluginSettings } from 'src/components/obsidian/SettingsTab';
import {
ChessifyDataAdapter,
ChessifyFileData,
ChessStudyDataAdapter,
ChessStudyFileData,
parseUserConfig,
} from 'src/utils';
import { ChessGroundSettings, ChessgroundWrapper } from './ChessgroundWrapper';
import { CommentSection } from './CommentSection';
import { PgnViewer } from './PgnViewer';
export type ChessifyConfig = ChessGroundSettings;
export type ChessStudyConfig = ChessGroundSettings;
interface AppProps {
source: string;
app: App;
pluginSettings: ChessifyPluginSettings;
chessifyData: ChessifyFileData;
dataAdapter: ChessifyDataAdapter;
pluginSettings: ChessStudyPluginSettings;
chessStudyData: ChessStudyFileData;
dataAdapter: ChessStudyDataAdapter;
}
export const Chessify = ({
export const ChessStudy = ({
source,
pluginSettings,
chessifyData,
chessStudyData,
dataAdapter,
}: AppProps) => {
// Parse Obsidian / Code Block Settings
const { boardColor, boardOrientation, chessifyId } = parseUserConfig(
const { boardColor, boardOrientation, chessStudyId } = parseUserConfig(
pluginSettings,
source
);
const [chessifyDataModified] = useState(chessifyData);
const [chessStudyDataModified] = useState(chessStudyData);
// Setup Chessboard and Chess.js APIs
const [chessView, setChessView] = useState<Api | null>(null);
const chessLogic = useMemo(() => {
const chess = new Chess();
chessifyData.moves.forEach((move) => {
chessStudyData.moves.forEach((move) => {
chess.move({
from: move.from,
to: move.to,
@ -52,17 +52,17 @@ export const Chessify = ({
});
});
return chess;
}, [chessifyData.moves]);
}, [chessStudyData.moves]);
// Track Application State
const [history, setHistory] = useState<Move[]>([]);
const [isViewOnly, setIsViewOnly] = useState<boolean>(false);
const [currentMove, setCurrentMove] = useState<number>(0);
const [shapes, setShapes] = useState<DrawShape[][]>(
chessifyData.moves.map((data) => data.shapes)
chessStudyData.moves.map((data) => data.shapes)
);
const [comments, setComments] = useState<(JSONContent | null)[]>(
chessifyData.moves.map((data) => data.comment)
chessStudyData.moves.map((data) => data.comment)
);
//PgnViewer Functions
@ -118,8 +118,8 @@ export const Chessify = ({
);
const onSaveButtonClick = useCallback(async () => {
const chessifyData: ChessifyFileData = {
header: chessifyDataModified.header,
const chessStudyData: ChessStudyFileData = {
header: chessStudyDataModified.header,
moves: chessLogic.history({ verbose: true }).map((move, index) => ({
...move,
variants: [],
@ -128,13 +128,13 @@ export const Chessify = ({
})),
};
await dataAdapter.saveFile(chessifyData, chessifyId);
await dataAdapter.saveFile(chessStudyData, chessStudyId);
new Notice('Save successfull!');
}, [
chessLogic,
chessifyDataModified.header,
chessifyId,
chessStudyDataModified.header,
chessStudyId,
comments,
dataAdapter,
shapes,
@ -157,7 +157,7 @@ export const Chessify = ({
<ChessgroundWrapper
api={chessView}
setApi={setChessView}
chessifyId={chessifyId}
chessStudyId={chessStudyId}
config={{
orientation: boardOrientation,
}}

View file

@ -11,7 +11,7 @@ import { playOtherSide, toColor, toDests } from 'src/utils';
export interface ChessGroundSettings {
api: Api | null;
setApi: React.Dispatch<React.SetStateAction<Api>>;
chessifyId: string;
chessStudyId: string;
config?: Config;
boardColor?: 'brown' | 'green';
chess: Chess;
@ -27,7 +27,7 @@ export const ChessgroundWrapper = React.memo(
({
api,
setApi,
chessifyId,
chessStudyId,
boardColor = 'green',
config = {},
chess,
@ -78,7 +78,7 @@ export const ChessgroundWrapper = React.memo(
ref,
chess,
api,
chessifyId,
chessStudyId,
config,
setApi,
setHistory,

View file

@ -3,13 +3,13 @@ import { Editor, Notice, Plugin } from 'obsidian';
import { ReactView } from './components/ReactView';
import { PgnModal } from './components/obsidian/PgnModal';
import {
ChessifyPluginSettings,
ChessStudyPluginSettings,
DEFAULT_SETTINGS,
SettingsTab,
} from './components/obsidian/SettingsTab';
import {
ChessifyDataAdapter,
ChessifyFileData,
ChessStudyDataAdapter,
ChessStudyFileData,
parseUserConfig,
} from './utils';
@ -20,9 +20,9 @@ import 'chessground/assets/chessground.brown.css';
import 'chessground/assets/chessground.cburnett.css';
import './main.css';
export default class ChessifyPlugin extends Plugin {
settings: ChessifyPluginSettings;
dataAdapter: ChessifyDataAdapter;
export default class ChessStudyPlugin extends Plugin {
settings: ChessStudyPluginSettings;
dataAdapter: ChessStudyDataAdapter;
storagePath = `${this.app.vault.configDir}/plugins/${this.manifest.id}/storage/`;
async onload() {
@ -30,7 +30,7 @@ export default class ChessifyPlugin extends Plugin {
await this.loadSettings();
// Register Data Adapter
this.dataAdapter = new ChessifyDataAdapter(
this.dataAdapter = new ChessStudyDataAdapter(
this.app.vault.adapter,
this.storagePath
);
@ -40,7 +40,7 @@ export default class ChessifyPlugin extends Plugin {
// Add command
this.addCommand({
id: 'insert-chesser',
id: 'insert-chess-study',
name: 'Insert PGN-Editor at cursor position',
editorCallback: (editor: Editor) => {
const cursorPosition = editor.getCursor();
@ -56,7 +56,7 @@ export default class ChessifyPlugin extends Plugin {
});
}
const chessifyFileData: ChessifyFileData = {
const chessStudyFileData: ChessStudyFileData = {
header: {
title: chess.header()['opening'] || null,
},
@ -68,13 +68,14 @@ export default class ChessifyPlugin extends Plugin {
})),
};
const id = await this.dataAdapter.saveFile(chessifyFileData);
const id = await this.dataAdapter.saveFile(chessStudyFileData);
editor.replaceRange(
`\`\`\`chessify\nchessifyId: ${id}\n\`\`\``,
`\`\`\`chessStudy\nchessStudyId: ${id}\nboardOrientation: white\nboardColor: green\n\`\`\``,
cursorPosition
);
} catch (e) {
console.log(e);
new Notice('There was an error during PGN parsing.', 0);
}
};
@ -83,20 +84,20 @@ export default class ChessifyPlugin extends Plugin {
},
});
// Add chessify code block processor
// Add chess study code block processor
this.registerMarkdownCodeBlockProcessor(
'chessify',
'chessStudy',
async (source, el, ctx) => {
const { chessifyId } = parseUserConfig(this.settings, source);
const { chessStudyId } = parseUserConfig(this.settings, source);
if (!chessifyId.trim().length)
if (!chessStudyId.trim().length)
return new Notice(
"No chessifyId parameter found, please add one manually if the file already exists or add it via the 'Insert PGN-Editor at cursor position' command.",
"No chessStudyId parameter found, please add one manually if the file already exists or add it via the 'Insert PGN-Editor at cursor position' command.",
0
);
try {
const data = await this.dataAdapter.loadFile(chessifyId);
const data = await this.dataAdapter.loadFile(chessStudyId);
ctx.addChild(
new ReactView(
@ -110,18 +111,18 @@ export default class ChessifyPlugin extends Plugin {
);
} catch (e) {
new Notice(
`There was an error while trying to load ${chessifyId}.json. You can check the plugin folder if the file exist and if not add one via the 'Insert PGN-Editor at cursor position' command.`,
`There was an error while trying to load ${chessStudyId}.json. You can check the plugin folder if the file exist and if not add one via the 'Insert PGN-Editor at cursor position' command.`,
0
);
}
}
);
console.log('Chessify successfully loaded');
console.log('Chess Study Plugin successfully loaded');
}
async onunload() {
console.log('Chessify successfully unloaded');
console.log('Chess Study Plugin successfully unloaded');
}
async loadSettings() {

View file

@ -5,25 +5,25 @@ import { Config } from 'chessground/config';
import { DrawShape } from 'chessground/draw';
import { nanoid } from 'nanoid';
import { DataAdapter, parseYaml } from 'obsidian';
import { ChessifyPluginSettings } from 'src/components/obsidian/SettingsTab';
import { ChessStudyPluginSettings } from 'src/components/obsidian/SettingsTab';
//Chess Logic
type ChessifyAppConfig = ChessifyPluginSettings & {
chessifyId: string;
type ChessStudyAppConfig = ChessStudyPluginSettings & {
chessStudyId: string;
};
export const parseUserConfig = (
settings: ChessifyPluginSettings,
settings: ChessStudyPluginSettings,
content: string
): ChessifyAppConfig => {
const chessifyConfig: ChessifyAppConfig = {
): ChessStudyAppConfig => {
const chessStudyConfig: ChessStudyAppConfig = {
...settings,
chessifyId: '',
chessStudyId: '',
};
try {
return {
...chessifyConfig,
...chessStudyConfig,
...parseYaml(content),
};
} catch (e) {
@ -77,17 +77,17 @@ export function playOtherSide(cg: Api, chess: Chess) {
//Storage Logic
interface ChessifyMove extends Move {
interface ChessStudyMove extends Move {
variants: Move[][];
shapes: DrawShape[];
comment: JSONContent | null;
}
export interface ChessifyFileData {
export interface ChessStudyFileData {
header: { title: string | null };
moves: ChessifyMove[];
moves: ChessStudyMove[];
}
export class ChessifyDataAdapter {
export class ChessStudyDataAdapter {
adapter: DataAdapter;
storagePath: string;
@ -96,18 +96,18 @@ export class ChessifyDataAdapter {
this.storagePath = storagePath;
}
async saveFile(data: ChessifyFileData, id?: string) {
const chessifyId = id || nanoid();
async saveFile(data: ChessStudyFileData, id?: string) {
const chessStudyId = id || nanoid();
await this.adapter.write(
`${this.storagePath}/${chessifyId}.json`,
`${this.storagePath}/${chessStudyId}.json`,
JSON.stringify(data, null, 2),
{}
);
return chessifyId;
return chessStudyId;
}
async loadFile(id: string): Promise<ChessifyFileData> {
async loadFile(id: string): Promise<ChessStudyFileData> {
const data = await this.adapter.read(`${this.storagePath}/${id}.json`);
return JSON.parse(data);
}