Merge pull request #17 from kkzzhizhou/main
Show task notes and add rewards panel. UI Overhaul. Credit to @kkzzhizhou!
This commit is contained in:
commit
8deee0ecc6
19 changed files with 240 additions and 93 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -6,6 +6,9 @@
|
||||||
node_modules
|
node_modules
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn.lock
|
||||||
|
|
||||||
|
|
||||||
*.js.map
|
*.js.map
|
||||||
|
|
||||||
|
|
|
||||||
0
.hotreload
Normal file
0
.hotreload
Normal file
|
|
@ -5,7 +5,8 @@
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "rollup --config rollup.config.js -w",
|
"dev": "rollup --config rollup.config.js -w",
|
||||||
"build": "rollup --config rollup.config.js --environment BUILD:production"
|
"build": "rollup --config rollup.config.js --environment BUILD:production",
|
||||||
|
"dev2": "obsidian-plugin dev src/main.ts"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "Leonard and Ran",
|
"author": "Leonard and Ran",
|
||||||
|
|
@ -21,6 +22,7 @@
|
||||||
"css-loader": "^6.4.0",
|
"css-loader": "^6.4.0",
|
||||||
"extract-text-webpack-plugin": "^2.1.2",
|
"extract-text-webpack-plugin": "^2.1.2",
|
||||||
"obsidian": "^0.12.0",
|
"obsidian": "^0.12.0",
|
||||||
|
"obsidian-plugin-cli": "^0.4.3",
|
||||||
"rollup": "^2.32.1",
|
"rollup": "^2.32.1",
|
||||||
"style-loader": "^3.3.0",
|
"style-loader": "^3.3.0",
|
||||||
"tslib": "^2.2.0",
|
"tslib": "^2.2.0",
|
||||||
|
|
@ -32,6 +34,7 @@
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-emoji-render": "^1.2.4",
|
"react-emoji-render": "^1.2.4",
|
||||||
|
"react-markdown": "^7.1.0",
|
||||||
"react-tabs": "^3.2.2"
|
"react-tabs": "^3.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ export default class HabiticaSync extends Plugin {
|
||||||
view: HabiticaSyncView;
|
view: HabiticaSyncView;
|
||||||
|
|
||||||
async onload() {
|
async onload() {
|
||||||
|
console.log("load plugin: habitica-sync")
|
||||||
await this.loadSettings();
|
await this.loadSettings();
|
||||||
this.addSettingTab(new HabiticaSyncSettingsTab(this.app, this));
|
this.addSettingTab(new HabiticaSyncSettingsTab(this.app, this));
|
||||||
this.registerView(
|
this.registerView(
|
||||||
|
|
@ -32,6 +33,8 @@ export default class HabiticaSync extends Plugin {
|
||||||
this.activateView();
|
this.activateView();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.activateView();
|
||||||
|
|
||||||
}
|
}
|
||||||
async loadSettings() {
|
async loadSettings() {
|
||||||
this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData())
|
this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData())
|
||||||
|
|
@ -39,8 +42,9 @@ export default class HabiticaSync extends Plugin {
|
||||||
async saveSettings() {
|
async saveSettings() {
|
||||||
await this.saveData(this.settings);
|
await this.saveData(this.settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
async onunload() {
|
async onunload() {
|
||||||
await this.view.onClose();
|
// await this.view.onClose();
|
||||||
|
|
||||||
this.app.workspace
|
this.app.workspace
|
||||||
.getLeavesOfType(VIEW_TYPE)
|
.getLeavesOfType(VIEW_TYPE)
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ export class HabiticaSyncView extends ItemView {
|
||||||
this.containerEl.children[1]
|
this.containerEl.children[1]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async onClose(){
|
async onClose(){
|
||||||
ReactDOM.unmountComponentAtNode(this.containerEl.children[1]);
|
ReactDOM.unmountComponentAtNode(this.containerEl.children[1]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
141
src/view/App.tsx
141
src/view/App.tsx
|
|
@ -1,10 +1,10 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { Notice } from "obsidian";
|
import { Notice } from "obsidian";
|
||||||
import { getStats, scoreTask, makeCronReq } from "./habiticaAPI"
|
import { getStats, scoreTask, makeCronReq, costReward } from "./habiticaAPI"
|
||||||
import Statsview from "./Components/Statsview"
|
import Statsview from "./Components/Statsview"
|
||||||
import Taskview from "./Components/Taskview"
|
import Taskview from "./Components/Taskview"
|
||||||
|
|
||||||
class App extends React.Component<any,any> {
|
class App extends React.Component<any, any> {
|
||||||
private _username = "";
|
private _username = "";
|
||||||
public get username() {
|
public get username() {
|
||||||
return this._username;
|
return this._username;
|
||||||
|
|
@ -43,6 +43,7 @@ class App extends React.Component<any,any> {
|
||||||
this.handleChangeTodos = this.handleChangeTodos.bind(this);
|
this.handleChangeTodos = this.handleChangeTodos.bind(this);
|
||||||
this.handleChangeDailys = this.handleChangeDailys.bind(this);
|
this.handleChangeDailys = this.handleChangeDailys.bind(this);
|
||||||
this.handleChangeHabits = this.handleChangeHabits.bind(this);
|
this.handleChangeHabits = this.handleChangeHabits.bind(this);
|
||||||
|
this.handleChangeRewards = this.handleChangeRewards.bind(this);
|
||||||
this.runCron = this.runCron.bind(this);
|
this.runCron = this.runCron.bind(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -50,15 +51,17 @@ class App extends React.Component<any,any> {
|
||||||
let cronDate = new Date(lastCron);
|
let cronDate = new Date(lastCron);
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
if (cronDate.getDate() != now.getDate() || (cronDate.getMonth() != now.getMonth() || cronDate.getFullYear() != now.getFullYear())) {
|
if (cronDate.getDate() != now.getDate() || (cronDate.getMonth() != now.getMonth() || cronDate.getFullYear() != now.getFullYear())) {
|
||||||
return(
|
// return (
|
||||||
<div className="cron">
|
// <div className="cron">
|
||||||
<div id="cronMessage"> Welcome back! Please check your tasks for the last day and hit continue to get your daily rewards. </div>
|
// <div id="cronMessage"> Welcome back! Please check your tasks for the last day and hit continue to get your daily rewards. </div>
|
||||||
<button onClick={this.runCron}>Continue</button>
|
// <button onClick={this.runCron}>Continue</button>
|
||||||
</div>
|
// </div>
|
||||||
);
|
// );
|
||||||
|
return (
|
||||||
|
<div className="cron"></div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log("Cron is up to date");
|
|
||||||
return null
|
return null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -77,100 +80,128 @@ class App extends React.Component<any,any> {
|
||||||
}
|
}
|
||||||
async reloadData() {
|
async reloadData() {
|
||||||
try {
|
try {
|
||||||
let response = await getStats(this.username, this.credentials);
|
let response = await getStats(this.username, this.credentials);
|
||||||
let result = await response.json();
|
let result = await response.json();
|
||||||
if (result.success === false) {
|
if (result.success === false) {
|
||||||
new Notice('Login Failed, Please check credentials and try again!');
|
new Notice('Login Failed, Please check credentials and try again!');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log(result);
|
this.setState({
|
||||||
this.setState({
|
isLoaded: true,
|
||||||
isLoaded: true,
|
user_data: result,
|
||||||
user_data: result,
|
tasks: result.tasks,
|
||||||
tasks: result.tasks,
|
});
|
||||||
});
|
}
|
||||||
}
|
} catch (e) {
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
console.log(e);
|
||||||
new Notice("API Error: Please check credentials")
|
new Notice("API Error: Please check credentials")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.reloadData()
|
this.reloadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendScore(id:string , score: string, message: string){
|
async sendScore(id: string, score: string, message: string) {
|
||||||
try {
|
try {
|
||||||
let response = await scoreTask(this.username, this.credentials, id, score);
|
let response = await scoreTask(this.username, this.credentials, id, score);
|
||||||
let result = await response.json();
|
let result = await response.json();
|
||||||
if(result.success === true){
|
if (result.success === true) {
|
||||||
new Notice(message);
|
new Notice(message);
|
||||||
this.reloadData();
|
this.reloadData();
|
||||||
} else {
|
} else {
|
||||||
new Notice("Resyncing, please try again");
|
new Notice("Resyncing, please try again");
|
||||||
this.reloadData();
|
this.reloadData();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
new Notice("API Error: Please check credentials")
|
new Notice("API Error: Please check credentials")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChangeTodos(event: any){
|
async sendReward(id: string, score: string, message: string) {
|
||||||
|
try {
|
||||||
|
let response = await costReward(this.username, this.credentials, id, score);
|
||||||
|
let result = await response.json();
|
||||||
|
if (result.success === true) {
|
||||||
|
new Notice(message);
|
||||||
|
this.reloadData();
|
||||||
|
} else {
|
||||||
|
new Notice("Resyncing, please try again");
|
||||||
|
this.reloadData();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
new Notice("API Error: Please check credentials")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChangeTodos(event: any) {
|
||||||
this.state.tasks.todos.forEach((element: any) => {
|
this.state.tasks.todos.forEach((element: any) => {
|
||||||
if(element.id == event.target.id){
|
if (element.id == event.target.id) {
|
||||||
if(!element.completed){
|
if (!element.completed) {
|
||||||
this.sendScore(event.target.id,"up", "Checked!")
|
this.sendScore(event.target.id, "up", "Checked!")
|
||||||
} else {
|
} else {
|
||||||
this.sendScore(event.target.id,"down", "Un-Checked!")
|
this.sendScore(event.target.id, "down", "Un-Checked!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
handleChangeDailys(event: any){
|
|
||||||
|
|
||||||
|
handleChangeDailys(event: any) {
|
||||||
this.state.tasks.dailys.forEach((element: any) => {
|
this.state.tasks.dailys.forEach((element: any) => {
|
||||||
if(element.id == event.target.id){
|
if (element.id == event.target.id) {
|
||||||
if(element.id == event.target.id){
|
if (element.id == event.target.id) {
|
||||||
if(!element.completed){
|
if (!element.completed) {
|
||||||
this.sendScore(event.target.id,"up", "Checked!")
|
this.sendScore(event.target.id, "up", "Checked!")
|
||||||
} else {
|
} else {
|
||||||
this.sendScore(event.target.id,"down", "Un-Checked!")
|
this.sendScore(event.target.id, "down", "Un-Checked!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
handleChangeHabits(event: any){
|
handleChangeHabits(event: any) {
|
||||||
const target_id = event.target.id.slice(4)
|
const target_id = event.target.id.slice(4)
|
||||||
if(event.target.id.slice(0,4) == "plus"){
|
if (event.target.id.slice(0, 4) == "plus") {
|
||||||
this.state.tasks.habits.forEach((element: any) => {
|
this.state.tasks.habits.forEach((element: any) => {
|
||||||
if(element.id == target_id){
|
if (element.id == target_id) {
|
||||||
this.sendScore(target_id,"up", "Plus!")
|
this.sendScore(target_id, "up", "Plus!")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.state.tasks.habits.forEach((element: any) => {
|
this.state.tasks.habits.forEach((element: any) => {
|
||||||
if(element.id == target_id){
|
if (element.id == target_id) {
|
||||||
this.sendScore(target_id,"down", "Minus :(")
|
this.sendScore(target_id, "down", "Minus :(")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
handleChangeRewards(event: any) {
|
||||||
render(){
|
const target_id = event.target.id
|
||||||
|
this.state.tasks.rewards.forEach((element: any) => {
|
||||||
|
if (element.id == event.target.id) {
|
||||||
|
if (element.id == target_id) {
|
||||||
|
this.sendReward(target_id, "down", "Cost!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
render() {
|
||||||
let content = this.CheckCron(this.state.user_data.lastCron);
|
let content = this.CheckCron(this.state.user_data.lastCron);
|
||||||
if(this.state.error)
|
if (this.state.error)
|
||||||
return(<div className="loading">Loading....</div>)
|
return (<div className="loading">Loading....</div>)
|
||||||
else if(!this.state.isLoaded)
|
else if (!this.state.isLoaded)
|
||||||
return <div className="loading">Loading....</div>
|
return <div className="loading">Loading....</div>
|
||||||
else {
|
else {
|
||||||
return (<div className="plugin-root">
|
return (<div className="plugin-root">
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
|
||||||
<Statsview user_data={this.state.user_data} />
|
<Taskview data={this.state.tasks} handleChangeTodos={this.handleChangeTodos} handleChangeDailys={this.handleChangeDailys} handleChangeHabits={this.handleChangeHabits} handleChangeRewards={this.handleChangeRewards}/>
|
||||||
<Taskview data={this.state.tasks} handleChangeTodos={this.handleChangeTodos} handleChangeDailys={this.handleChangeDailys} handleChangeHabits={this.handleChangeHabits}/>
|
|
||||||
{content}
|
{content}
|
||||||
</div>
|
<div></div>
|
||||||
|
<Statsview user_data={this.state.user_data} />
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,11 @@ import * as React from 'react';
|
||||||
export default function Index(props: any) {
|
export default function Index(props: any) {
|
||||||
return(
|
return(
|
||||||
<div className="stats">
|
<div className="stats">
|
||||||
<div id="profile-name">{props.user_data.profile.name}</div>
|
{/* <div id="profile-name">{props.user_data.profile.name}</div> */}
|
||||||
<div className = "substats" id="hp"><i className="material-icons">favorite</i>HP: {(props.user_data.stats.hp).toPrecision(3)}</div>
|
{console.log(props)}
|
||||||
<div className = "substats" id="lvl"><i className="material-icons">star</i>LVL: {props.user_data.stats.lvl}</div>
|
<div className = "substats" id="hp">HP: {(props.user_data.stats.hp).toPrecision(3)}</div>
|
||||||
|
<div className = "substats" id="lvl">LEVEL: {props.user_data.stats.lvl}</div>
|
||||||
|
<div className = "substats" id="gold">GOLD: {(props.user_data.stats.gp).toPrecision(3)}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
import Emoji from "react-emoji-render";
|
import Emoji from "react-emoji-render";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import ReactMarkdown from "react-markdown";
|
||||||
|
|
||||||
function DailyItem(props: any) {
|
function DailyItem(props: any) {
|
||||||
return (
|
return (
|
||||||
<div className="todo-item" id={props.id}>
|
<div className="todo-item" id={props.id}>
|
||||||
<input type="checkbox" className="checkbox" id={props.id} onChange={props.onChange} checked={props.completed}/>
|
<input type="checkbox" className="checkbox" id={props.id} onChange={props.onChange} checked={props.completed} />
|
||||||
<p><Emoji text={props.daily_text}></Emoji></p>
|
<div>
|
||||||
|
<p><Emoji text={props.daily_text}></Emoji></p>
|
||||||
|
<ReactMarkdown children={props.daily_notes} />
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ export default function Index(props: any){
|
||||||
else {
|
else {
|
||||||
const incompleteDailies = props.dailys.map((daily: any) => {
|
const incompleteDailies = props.dailys.map((daily: any) => {
|
||||||
if(!daily.completed)
|
if(!daily.completed)
|
||||||
return <DailyItem key={daily.id} id={daily.id}daily_text={daily.text} onChange={props.onChange} completed={daily.completed}/>
|
return <DailyItem key={daily.id} id={daily.id} daily_text={daily.text} daily_notes={daily.notes} onChange={props.onChange} completed={daily.completed}/>
|
||||||
})
|
})
|
||||||
const completedDailies = props.dailys.map((daily: any) => {
|
const completedDailies = props.dailys.map((daily: any) => {
|
||||||
if(daily.completed)
|
if(daily.completed)
|
||||||
return <DailyItem key={daily.id} id={daily.id}daily_text={daily.text} onChange={props.onChange} completed={daily.completed}/>
|
return <DailyItem key={daily.id} id={daily.id} daily_text={daily.text} daily_notes={daily.notes} onChange={props.onChange} completed={daily.completed}/>
|
||||||
})
|
})
|
||||||
const display = <div id="classDisplay">
|
const display = <div id="classDisplay">
|
||||||
<Tabs>
|
<Tabs>
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
import Emoji from "react-emoji-render";
|
import Emoji from "react-emoji-render";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import ReactMarkdown from "react-markdown";
|
||||||
|
|
||||||
function HabitItem(props: any) {
|
function HabitItem(props: any) {
|
||||||
return (
|
return (
|
||||||
<div className="habit-item" id={props.id}>
|
<div className="habit-item" id={props.id}>
|
||||||
<button className="habit-plus" id={"plus"+props.id} onClick={props.onChange}>
|
<button className="habit-plus" id={"plus" + props.id} onClick={props.onChange}>
|
||||||
+{props.upCount}
|
+{props.upCount}
|
||||||
</button>
|
</button>
|
||||||
<p className="habit-text"><Emoji text = {props.habit_text}></Emoji></p>
|
<button className="habit-minus" id={"mins" + props.id} onClick={props.onChange}>
|
||||||
<button className="habit-minus" id={"mins"+props.id} onClick={props.onChange}>
|
|
||||||
-{props.downCount}
|
-{props.downCount}
|
||||||
</button>
|
</button>
|
||||||
|
<div>
|
||||||
|
<p className="habit-text"><Emoji text={props.habit_text}></Emoji></p>
|
||||||
|
<ReactMarkdown children={props.habit_notes} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export default function Index(props: any){
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const allHabits = props.habits.map((habit: any) => {
|
const allHabits = props.habits.map((habit: any) => {
|
||||||
return <HabitItem key={habit.id} id={habit.id} habit_text={habit.text} upCount={habit.counterUp} downCount={habit.counterDown} onChange={props.onChange}/>
|
return <HabitItem key={habit.id} id={habit.id} habit_text={habit.text} habit_notes={habit.notes} upCount={habit.counterUp} downCount={habit.counterDown} onChange={props.onChange}/>
|
||||||
})
|
})
|
||||||
const display = <div id="classDisplay">
|
const display = <div id="classDisplay">
|
||||||
<ul>{allHabits}</ul>
|
<ul>{allHabits}</ul>
|
||||||
|
|
|
||||||
17
src/view/Components/Taskview/Rewardview/RewardItem.tsx
Normal file
17
src/view/Components/Taskview/Rewardview/RewardItem.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import Emoji from "react-emoji-render";
|
||||||
|
import * as React from "react";
|
||||||
|
import ReactMarkdown from "react-markdown";
|
||||||
|
function RewardItem(props: any) {
|
||||||
|
return (
|
||||||
|
<div className="reward-item" id={props.id}>
|
||||||
|
<button className="reward-click" id={props.id} onClick={props.onChange}>-{props.reward_value}</button>
|
||||||
|
<div>
|
||||||
|
<p className="reward-text"><Emoji text={props.reward_text}></Emoji></p>
|
||||||
|
<ReactMarkdown children={props.reward_notes} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RewardItem
|
||||||
21
src/view/Components/Taskview/Rewardview/index.tsx
Normal file
21
src/view/Components/Taskview/Rewardview/index.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import RewardItem from "./RewardItem"
|
||||||
|
|
||||||
|
export default function Index(props: any){
|
||||||
|
if(props.rewards == undefined) {
|
||||||
|
return (<div id="classDisplay">
|
||||||
|
No Rewards present.
|
||||||
|
</div>)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const allRewards = props.rewards.map((reward: any) => {
|
||||||
|
return <RewardItem key={reward.id} id={reward.id} reward_text={reward.text} reward_notes={reward.notes} reward_value={reward.value} onChange={props.onChange}/>
|
||||||
|
})
|
||||||
|
const display = <div id="classDisplay">
|
||||||
|
<ul>{allRewards}</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
return(display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -5,7 +5,7 @@ function TodoItem(props: any) {
|
||||||
return (
|
return (
|
||||||
<div className="todo-item" id={props.id}>
|
<div className="todo-item" id={props.id}>
|
||||||
<input type="checkbox" className="checkbox" id={props.id} onChange={props.onChange} checked={props.completed}/>
|
<input type="checkbox" className="checkbox" id={props.id} onChange={props.onChange} checked={props.completed}/>
|
||||||
<Emoji text = {props.todo_text}></Emoji>
|
<Emoji text = {props.todo_text}></Emoji><Emoji text = {props.todo_text}></Emoji>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
import Emoji from "react-emoji-render";
|
import Emoji from "react-emoji-render";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import ReactMarkdown from "react-markdown";
|
||||||
|
|
||||||
function TodoItem(props: any) {
|
function TodoItem(props: any) {
|
||||||
return (
|
return (
|
||||||
<div className="todo-item" id={props.id}>
|
<div className="todo-item" id={props.id}>
|
||||||
<input type="checkbox" className="checkbox" id={props.id} onChange={props.onChange} checked={props.completed}/>
|
<input type="checkbox" className="checkbox" id={props.id} onChange={props.onChange} checked={props.completed}/>
|
||||||
<p><Emoji text ={props.todo_text}></Emoji></p>
|
{/* <p><Emoji text ={props.todo_text}></Emoji></p> */}
|
||||||
|
<div>
|
||||||
|
<p><Emoji text={props.todo_text}></Emoji></p>
|
||||||
|
<ReactMarkdown children={props.todo_notes} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ export default function Index(props: any){
|
||||||
else {
|
else {
|
||||||
const incompleteTodos = props.todos.map((todo: any) => {
|
const incompleteTodos = props.todos.map((todo: any) => {
|
||||||
if(!todo.completed)
|
if(!todo.completed)
|
||||||
return <TodoItem key={todo.id} id={todo.id} todo_text={todo.text} onChange={props.onChange} completed={todo.completed}/>
|
return <TodoItem key={todo.id} id={todo.id} todo_text={todo.text} todo_notes={todo.notes} onChange={props.onChange} completed={todo.completed}/>
|
||||||
})
|
})
|
||||||
const completedTodos = props.todos.map((todo: any) => {
|
const completedTodos = props.todos.map((todo: any) => {
|
||||||
if(todo.completed)
|
if(todo.completed)
|
||||||
return <TodoItem key={todo.id} id={todo.id} todo_text={todo.text} onChange={props.onChange} completed={todo.completed}/>
|
return <TodoItem key={todo.id} id={todo.id} todo_text={todo.text} todo_notes={todo.notes} onChange={props.onChange} completed={todo.completed}/>
|
||||||
})
|
})
|
||||||
const display = <div id="classDisplay">
|
const display = <div id="classDisplay">
|
||||||
<Tabs>
|
<Tabs>
|
||||||
|
|
|
||||||
|
|
@ -2,31 +2,39 @@ import * as React from "react";
|
||||||
import Dailiesview from "./Dailiesview"
|
import Dailiesview from "./Dailiesview"
|
||||||
import Habitsview from "./Habitsview"
|
import Habitsview from "./Habitsview"
|
||||||
import Todoview from "./Todoview"
|
import Todoview from "./Todoview"
|
||||||
|
import Rewardview from "./Rewardview"
|
||||||
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
|
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
|
||||||
|
|
||||||
export default function Index(props: any){
|
export default function Index(props: any){
|
||||||
const display = <div className="task-view">
|
const display = <div className="task-view">
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<TabList>
|
<TabList>
|
||||||
<Tab >
|
|
||||||
<span className="material-icons md-24">task_alt</span>
|
|
||||||
</Tab>
|
|
||||||
<Tab>
|
<Tab>
|
||||||
<span className="material-icons md-24">today</span>
|
<span className="material-icons md-24">today</span>
|
||||||
</Tab>
|
</Tab>
|
||||||
|
<Tab >
|
||||||
|
<span className="material-icons md-24">add_chart</span>
|
||||||
|
</Tab>
|
||||||
<Tab>
|
<Tab>
|
||||||
<span className="material-icons md-24">add_circle_outline</span>
|
<span className="material-icons md-24">assignment_turned_in</span>
|
||||||
|
</Tab>
|
||||||
|
<Tab>
|
||||||
|
<span className="material-icons md-24">account_balance</span>
|
||||||
</Tab>
|
</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
<TabPanel>
|
|
||||||
<Habitsview habits={props.data.habits} onChange={props.handleChangeHabits}/>
|
|
||||||
</TabPanel>
|
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<Dailiesview dailys={props.data.dailys} onChange={props.handleChangeDailys} />
|
<Dailiesview dailys={props.data.dailys} onChange={props.handleChangeDailys} />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
<TabPanel>
|
||||||
|
<Habitsview habits={props.data.habits} onChange={props.handleChangeHabits}/>
|
||||||
|
</TabPanel>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<Todoview todos={props.data.todos} onChange={props.handleChangeTodos} />
|
<Todoview todos={props.data.todos} onChange={props.handleChangeTodos} />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
<TabPanel>
|
||||||
|
<Rewardview rewards={props.data.rewards} onChange={props.handleChangeRewards} />
|
||||||
|
</TabPanel>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
return(display);
|
return(display);
|
||||||
|
|
|
||||||
|
|
@ -40,3 +40,17 @@ export async function makeCronReq(username: string, credentials: string){
|
||||||
})
|
})
|
||||||
return(response)
|
return(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function costReward(username: string, credentials: string, taskID: string, direction: string) {
|
||||||
|
const url = "https://habitica.com/api/v4/tasks/".concat(taskID).concat("/score/").concat(direction)
|
||||||
|
const response = fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"x-client": "278e719e-5f9c-43b1-9dba-8b73343dc062-HabiticaSync",
|
||||||
|
"x-api-user": username,
|
||||||
|
"x-api-key": credentials,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return(response)
|
||||||
|
}
|
||||||
|
|
|
||||||
47
styles.css
47
styles.css
|
|
@ -1,3 +1,8 @@
|
||||||
|
* {
|
||||||
|
/* margin: 0; */
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#profile-name {
|
#profile-name {
|
||||||
font-size: x-large;
|
font-size: x-large;
|
||||||
|
|
@ -5,7 +10,8 @@
|
||||||
padding-bottom: 3%;
|
padding-bottom: 3%;
|
||||||
}
|
}
|
||||||
.stats {
|
.stats {
|
||||||
padding-bottom: 6px;
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-item {
|
.todo-item {
|
||||||
|
|
@ -13,25 +19,38 @@
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0px 0px 0;
|
padding: 0px 0px 0;
|
||||||
width: 80%;
|
width: 100%;
|
||||||
border-bottom: 1px solid #cecece;
|
border-bottom: 1px solid #cecece;
|
||||||
font-family: Roboto, sans-serif;
|
font-family: Roboto, sans-serif;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reward-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0px 0px 0;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid #cecece;
|
||||||
|
font-family: Roboto, sans-serif;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.habit-text {
|
.habit-text {
|
||||||
text-align: center !important;
|
text-align: left !important;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
width: 50%;
|
width: 80%;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.habit-plus {
|
.habit-plus {
|
||||||
/* background-color: #fff; */
|
/* background-color: #fff; */
|
||||||
border: none;
|
border: none;
|
||||||
color: white;
|
/* color: black; */
|
||||||
padding: 7px 10px;
|
padding: 7px 5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
@ -41,8 +60,8 @@
|
||||||
/* background-color: #fff; */
|
/* background-color: #fff; */
|
||||||
/* border-radius: 50%; */
|
/* border-radius: 50%; */
|
||||||
border: none;
|
border: none;
|
||||||
color: white;
|
/* color: black; */
|
||||||
padding: 7px 10px;
|
padding: 7px 5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
@ -70,8 +89,19 @@ input[type=checkbox]:focus {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.task-view {
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none; /* Chrome Safari */
|
||||||
|
}
|
||||||
|
|
||||||
.plugin-root {
|
.plugin-root {
|
||||||
min-width: 260px;
|
min-width: 260px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: 93% 5% 2%;
|
||||||
|
height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.substats {
|
.substats {
|
||||||
|
|
@ -144,6 +174,7 @@ input[type=checkbox]:focus {
|
||||||
|
|
||||||
.react-tabs__tab-panel {
|
.react-tabs__tab-panel {
|
||||||
display: none;
|
display: none;
|
||||||
|
left: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-tabs__tab-panel--selected {
|
.react-tabs__tab-panel--selected {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue