Merge pull request #6 from SuperChamp234/task-menu

Refractored and features added
This commit is contained in:
SuperChamp234 2021-10-19 06:45:21 -07:00 committed by GitHub
commit 75b18f2f2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 634 additions and 75 deletions

218
main.js

File diff suppressed because one or more lines are too long

View file

@ -8,7 +8,7 @@
"build": "rollup --config rollup.config.js --environment BUILD:production" "build": "rollup --config rollup.config.js --environment BUILD:production"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "Leonard and Ran",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^18.0.0", "@rollup/plugin-commonjs": "^18.0.0",

View file

@ -1,8 +0,0 @@
import * as React from "react";
import App from "./view/App";
export default function ReactView(props: any){
return(
<App username={props.userID} apiToken={props.tokenAPI} plugin={props.plugin}/>
)
}

View file

@ -1,7 +1,7 @@
import { ItemView,WorkspaceLeaf } from "obsidian"; import { ItemView,WorkspaceLeaf } from "obsidian";
import * as React from "react"; import * as React from "react";
import * as ReactDOM from "react-dom"; import * as ReactDOM from "react-dom";
import ReactView from "./ReactView"; import App from "./view/App"
import HabiticaSync from "./main"; import HabiticaSync from "./main";
@ -27,7 +27,7 @@ export class HabiticaSyncView extends ItemView {
async onOpen() { async onOpen() {
ReactDOM.render( ReactDOM.render(
<ReactView userID = {this.plugin.settings.userID} tokenAPI = {this.plugin.settings.apiToken} plugin={this.plugin}/>, <App plugin={this.plugin}/>,
this.containerEl.children[1] this.containerEl.children[1]
) )
} }

View file

@ -9,8 +9,8 @@ let credentials = ""
class App extends React.Component<any,any> { class App extends React.Component<any,any> {
constructor(props: any) { constructor(props: any) {
super(props) super(props)
username = this.props.username username = this.props.plugin.settings.userID
credentials = this.props.apiToken credentials = this.props.plugin.settings.apiToken
this.state = { this.state = {
isLoaded: false, isLoaded: false,
user_data: { user_data: {
@ -22,9 +22,15 @@ class App extends React.Component<any,any> {
lvl: 0, lvl: 0,
} }
}, },
todos: [] todos: [],
dailys: [],
habits: [],
} }
this.handleChange = this.handleChange.bind(this) this.handleChangeTodos = this.handleChangeTodos.bind(this)
this.handleChangeDailys = this.handleChangeDailys.bind(this)
this.handleChangeHabits = this.handleChangeHabits.bind(this)
} }
sendNotice(message: string){ sendNotice(message: string){
this.props.plugin.displayNotice(message) this.props.plugin.displayNotice(message)
@ -36,14 +42,11 @@ class App extends React.Component<any,any> {
result => { result => {
if(result.success === false){ if(result.success === false){
this.sendNotice("Login Failed, Please check credentials and try again!") this.sendNotice("Login Failed, Please check credentials and try again!")
console.log(result)
} else { } else {
console.log(result)
console.log("data reloaded")
this.setState({ this.setState({
isLoaded: true, isLoaded: true,
user_data: result, user_data: result,
todos: result.tasks.todos tasks: result.tasks,
}) })
} }
}, },
@ -58,8 +61,8 @@ class App extends React.Component<any,any> {
componentDidMount() { componentDidMount() {
this.reloadData() this.reloadData()
} }
handleChange(event: any){ handleChangeTodos(event: any){
this.state.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){
scoreTask(username, credentials, event.target.id, "up") scoreTask(username, credentials, event.target.id, "up")
@ -103,6 +106,103 @@ class App extends React.Component<any,any> {
} }
}) })
} }
handleChangeDailys(event: any){
this.state.tasks.dailys.forEach((element: any) => {
if(element.id == event.target.id){
if(!element.completed){
scoreTask(username, credentials, event.target.id, "up")
.then(res => res.json())
.then(
result => {
if(result.success) {
this.sendNotice("Checked!")
console.log(result)
this.reloadData()
} else {
this.sendNotice("Resyncing, please try again")
this.reloadData()
}
},
(error) => {
this.sendNotice("API Error: Please Check crendentials and try again")
console.log(error)
}
)
} else {
scoreTask(username, credentials, event.target.id, "down")
.then(res => res.json())
.then(
result => {
if(result.success){
this.sendNotice("Un-checked!")
console.log(result)
this.reloadData()
} else {
this.sendNotice("Resyncing, please try again")
this.reloadData()
}
},
(error) => {
this.sendNotice("API Error: Please Check crendentials and try again")
console.log(error)
}
)
}
}
})
}
handleChangeHabits(event: any){
const target_id = event.target.id.slice(4)
console.log(target_id)
if(event.target.id.slice(0,4) == "plus"){
this.state.tasks.habits.forEach((element: any) => {
if(element.id == target_id){
scoreTask(username, credentials, target_id, "up")
.then(res => res.json())
.then(
result => {
if(result.success) {
this.sendNotice("Plus!")
console.log(result)
this.reloadData()
} else {
this.sendNotice("Resyncing, please try again")
this.reloadData()
}
},
(error) => {
this.sendNotice("API Error: Please Check crendentials and try again")
console.log(error)
}
)
}
})
}
else {
this.state.tasks.habits.forEach((element: any) => {
if(element.id == target_id){
scoreTask(username, credentials, target_id, "down")
.then(res => res.json())
.then(
result => {
if(result.success) {
this.sendNotice("Minus :(")
console.log(result)
this.reloadData()
} else {
this.sendNotice("Resyncing, please try again")
this.reloadData()
}
},
(error) => {
this.sendNotice("API Error: Please Check crendentials and try again")
console.log(error)
}
)
}
})
}
}
render(){ render(){
if(this.state.error) if(this.state.error)
@ -113,7 +213,7 @@ class App extends React.Component<any,any> {
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} /> <Statsview user_data={this.state.user_data} />
<Taskview todos={this.state.todos} onChange={this.handleChange} /> <Taskview data={this.state.tasks} handleChangeTodos={this.handleChangeTodos} handleChangeDailys={this.handleChangeDailys} handleChangeHabits={this.handleChangeHabits}/>
</div> </div>
); );
} }

View file

@ -0,0 +1,12 @@
import * as React from "react";
function DailyItem(props: any) {
return (
<div className="todo-item" id={props.id}>
<input type="checkbox" className="checkbox" id={props.id} onChange={props.onChange} checked={props.completed}/>
<p>{props.daily_text}</p>
</div>
)
}
export default DailyItem

View file

@ -0,0 +1,36 @@
import * as React from "react";
import DailyItem from "./DailyItem"
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
export default function Index(props: any){
if(props.dailys == undefined) {
return <div id="classDisplay">No Dailies Present</div>
}
else {
const incompleteDailies = props.dailys.map((daily: any) => {
if(!daily.completed)
return <DailyItem key={daily.id} id={daily.id}daily_text={daily.text} onChange={props.onChange} completed={daily.completed}/>
})
const completedDailies = props.dailys.map((daily: any) => {
if(daily.completed)
return <DailyItem key={daily.id} id={daily.id}daily_text={daily.text} onChange={props.onChange} completed={daily.completed}/>
})
const display = <div id="classDisplay">
<Tabs>
<TabList>
<Tab>Active</Tab>
<Tab>Completed</Tab>
</TabList>
<TabPanel>
<ul>{incompleteDailies}</ul>
</TabPanel>
<TabPanel>
<ul>{completedDailies}</ul>
</TabPanel>
</Tabs>
</div>
return(display);
}
}

View file

@ -0,0 +1,18 @@
import * as React from "react";
function HabitItem(props: any) {
console.log("plus"+props.id)
return (
<div className="habit-item" id={props.id}>
<button className="habit-plus" id={"plus"+props.id} onClick={props.onChange}>
+{props.upCount}
</button>
<p>{props.habit_text}</p>
<button className="habit-minus" id={"mins"+props.id} onClick={props.onChange}>
-{props.downCount}
</button>
</div>
)
}
export default HabitItem

View file

@ -0,0 +1,22 @@
import * as React from "react";
import HabitItem from "./HabitItem"
export default function Index(props: any){
if(props.habits == undefined) {
return (<div id="classDisplay">
No habits present.
</div>)
}
else {
console.log("habits = " + props.habits);
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}/>
})
const display = <div id="classDisplay">
<ul>{allHabits}</ul>
</div>
return(display);
}
}

View file

@ -0,0 +1,56 @@
.react-tabs {
-webkit-tap-highlight-color: transparent;
}
.react-tabs__tab-list {
border-bottom: 1px solid #aaa;
margin: 0 0 10px;
padding: 0;
}
.react-tabs__tab {
display: inline-block;
border: 1px solid transparent;
border-bottom: none;
bottom: -1px;
position: relative;
list-style: none;
padding: 6px 12px;
cursor: pointer;
}
.react-tabs__tab--selected {
background: #fff;
border-color: #aaa;
color: black;
border-radius: 5px 5px 0 0;
}
.react-tabs__tab--disabled {
color: GrayText;
cursor: default;
}
.react-tabs__tab:focus {
box-shadow: 0 0 5px hsl(208, 99%, 50%);
border-color: hsl(208, 99%, 50%);
outline: none;
}
.react-tabs__tab:focus:after {
content: "";
position: absolute;
height: 5px;
left: -4px;
right: -4px;
bottom: -5px;
background: #fff;
}
.react-tabs__tab-panel {
display: none;
}
.react-tabs__tab-panel--selected {
display: block;
}

View file

@ -0,0 +1 @@
import * as React from "react"

View file

@ -0,0 +1,12 @@
import * as React from "react";
function TodoItem(props: any) {
return (
<div className="todo-item" id={props.id}>
<input type="checkbox" className="checkbox" id={props.id} onChange={props.onChange} checked={props.completed}/>
<p>{props.todo_text}</p>
</div>
)
}
export default TodoItem

View file

@ -0,0 +1,36 @@
import * as React from "react";
import TodoItem from "./TodoItem"
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
export default function Index(props: any){
if(props.todos == undefined) {
return <div id="classDisplay">No Todos present.</div>
}
else {
const incompleteTodos = props.todos.map((todo: any) => {
if(!todo.completed)
return <TodoItem key={todo.id} id={todo.id} todo_text={todo.text} onChange={props.onChange} completed={todo.completed}/>
})
const completedTodos = props.todos.map((todo: any) => {
if(todo.completed)
return <TodoItem key={todo.id} id={todo.id} todo_text={todo.text} onChange={props.onChange} completed={todo.completed}/>
})
const display = <div id="classDisplay">
<Tabs>
<TabList>
<Tab>Active</Tab>
<Tab>Completed</Tab>
</TabList>
<TabPanel>
<ul>{incompleteTodos}</ul>
</TabPanel>
<TabPanel>
<ul>{completedTodos}</ul>
</TabPanel>
</Tabs>
</div>
return(display);
}
}

View file

@ -0,0 +1,58 @@
.react-tabs {
-webkit-tap-highlight-color: transparent;
}
.react-tabs__tab-list {
border-bottom: 1px solid #aaa;
margin: 0 0 10px;
padding: 0;
}
.react-tabs__tab {
display: inline-block;
border: 1px solid transparent;
border-bottom: none;
bottom: -1px;
position: relative;
list-style: none;
padding: 6px 12px;
cursor: pointer;
}
.react-tabs__tab--selected {
background: #fff;
border-color: #aaa;
color: black;
border-radius: 5px 5px 0 0;
}
.react-tabs__tab--disabled {
color: GrayText;
cursor: default;
}
.react-tabs__tab:focus {
box-shadow: 0 0 5px hsl(208, 99%, 50%);
border-color: hsl(208, 99%, 50%);
outline: none;
}
.re
.react-tabs__tab:focus:after {
content: "";
position: absolute;
height: 5px;
left: -4px;
right: -4px;
bottom: -5px;
background: #fff;
}
.react-tabs__tab-panel {
display: none;
}
.react-tabs__tab-panel--selected {
display: block;
}

View file

@ -0,0 +1 @@
import * as React from "react"

View file

@ -1,30 +1,34 @@
import * as React from "react"; import * as React from "react";
import TodoItem from "./TodoItem" import Dailiesview from "./Dailiesview"
import Habitsview from "./Habitsview"
import Todoview from "./Todoview"
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 incompleteTodos = props.todos.map((todo: any) => { const display = <div className="taskView">
if(!todo.completed)
return <TodoItem key={todo.id} id={todo.id} todo_text={todo.text} onChange={props.onChange} completed={todo.completed}/>
})
const completedTodos = props.todos.map((todo: any) => {
if(todo.completed)
return <TodoItem key={todo.id} id={todo.id} todo_text={todo.text} onChange={props.onChange} completed={todo.completed}/>
})
const display = <div id="classDisplay">
<Tabs> <Tabs>
<TabList> <TabList>
<Tab>Active Todos</Tab> <Tab>
<Tab>Completed Todos</Tab> <span className="material-icons md-24">task_alt</span>
</Tab>
<Tab>
<span className="material-icons">today</span>
</Tab>
<Tab>
<span className="material-icons">add_circle_outline</span>
</Tab>
</TabList> </TabList>
<TabPanel> <TabPanel>
<ul>{incompleteTodos}</ul> <Habitsview habits={props.data.habits} onChange={props.handleChangeHabits}/>
</TabPanel> </TabPanel>
<TabPanel> <TabPanel>
<ul>{completedTodos}</ul> <Dailiesview dailys={props.data.dailys} onChange={props.handleChangeDailys} />
</TabPanel>
<TabPanel>
<Todoview todos={props.data.todos} onChange={props.handleChangeTodos} />
</TabPanel> </TabPanel>
</Tabs> </Tabs>
</div> </div>
return(display); return(display);
} }

View file

@ -1,3 +1,4 @@
#profile-name { #profile-name {
font-size: x-large; font-size: x-large;
font-weight: bold; font-weight: bold;
@ -6,6 +7,12 @@
.stats { .stats {
padding-bottom: 6px; padding-bottom: 6px;
} }
.material-icons.md-18 { font-size: 18px; }
.material-icons.md-24 { font-size: 24px; }
.material-icons.md-36 { font-size: 36px; }
.material-icons.md-48 { font-size: 48px; }
.todo-item { .todo-item {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
@ -18,6 +25,40 @@
font-size: 16px; font-size: 16px;
} }
.habit-plus {
/* background-color: #fff; */
border-radius: 50%;
border: none;
color: white;
padding: 6px 10px;
text-align: center;
text-decoration: none;
font-size: 16px;
}
.habit-minus {
/* background-color: #fff; */
border-radius: 50%;
border: none;
color: white;
padding: 7px 10px;
text-align: center;
text-decoration: none;
font-size: 16px;
}
.habit-item {
display: flex;
justify-content: center;
align-items: center;
padding: 0px 0px 0;
width: 80%;
border-bottom: 1px solid #cecece;
font-family: Roboto, sans-serif;
font-weight: normal;
font-size: 16px;
}
input[type=checkbox] { input[type=checkbox] {
margin-right: 10px; margin-right: 10px;
} }