diff --git a/manifest.json b/manifest.json index b537c6e..c9b0afa 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-habitica-integration", "name": "Habitica Sync", - "version": "0.9.7", + "version": "0.9.15", "minAppVersion": "0.9.12", "description": "This plugin helps integrate Habitica user tasks and stats into Obsidian", "author": "Leoh and Ran", diff --git a/package.json b/package.json index 4acb414..344ca09 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "node-fetch": "^3.0.0", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-emoji-render": "^1.2.4", "react-tabs": "^3.2.2" } } diff --git a/src/view/App.tsx b/src/view/App.tsx index 3b1882d..6dda418 100644 --- a/src/view/App.tsx +++ b/src/view/App.tsx @@ -1,17 +1,30 @@ import * as React from "react"; import { Notice } from "obsidian"; -import { getStats, scoreTask } from "./habiticaAPI" +import { getStats, scoreTask, makeCronReq } from "./habiticaAPI" import Statsview from "./Components/Statsview" import Taskview from "./Components/Taskview" class App extends React.Component { - username = "" - credentials = "" + private _username = ""; + public get username() { + return this._username; + } + public set username(value) { + this._username = value; + } + private _credentials = ""; + public get credentials() { + return this._credentials; + } + public set credentials(value) { + this._credentials = value; + } constructor(props: any) { super(props) this.username = this.props.plugin.settings.userID this.credentials = this.props.plugin.settings.apiToken this.state = { + needCron: false, isLoaded: false, user_data: { profile: { @@ -20,18 +33,48 @@ class App extends React.Component { stats: { hp: 0, lvl: 0, - } + }, + lastCron: "", }, todos: [], dailys: [], habits: [], } - this.handleChangeTodos = this.handleChangeTodos.bind(this) - this.handleChangeDailys = this.handleChangeDailys.bind(this) - this.handleChangeHabits = this.handleChangeHabits.bind(this) - + this.handleChangeTodos = this.handleChangeTodos.bind(this); + this.handleChangeDailys = this.handleChangeDailys.bind(this); + this.handleChangeHabits = this.handleChangeHabits.bind(this); + this.runCron = this.runCron.bind(this); } + CheckCron(lastCron: string) { + let cronDate = new Date(lastCron); + let now = new Date(); + if (cronDate.getDate() != now.getDate() || (cronDate.getMonth() != now.getMonth() || cronDate.getFullYear() != now.getFullYear())) { + return( +
+
Welcome back! Please check your tasks for the last day and hit continue to get your daily rewards.
+ +
+ ); + } + else { + console.log("Cron is up to date"); + return null + }; + } + async runCron() { + console.log("running cron"); + try { + let response = await makeCronReq(this.username, this.credentials); + this.setState({ + needCron: false, + }) + } catch (error) { + console.log(error); + new Notice("There was an error running the cron. Please try again later."); + } + this.reloadData(); + } async reloadData() { try { let response = await getStats(this.username, this.credentials); @@ -40,6 +83,7 @@ class App extends React.Component { new Notice('Login Failed, Please check credentials and try again!'); } else { + console.log(result); this.setState({ isLoaded: true, user_data: result, @@ -115,6 +159,7 @@ class App extends React.Component { } render(){ + let content = this.CheckCron(this.state.user_data.lastCron); if(this.state.error) return(
Loading....
) else if(!this.state.isLoaded) @@ -124,6 +169,7 @@ class App extends React.Component { + {content} ); } diff --git a/src/view/Components/Taskview/Dailiesview/DailyItem.tsx b/src/view/Components/Taskview/Dailiesview/DailyItem.tsx index 40650af..d2d308e 100644 --- a/src/view/Components/Taskview/Dailiesview/DailyItem.tsx +++ b/src/view/Components/Taskview/Dailiesview/DailyItem.tsx @@ -1,10 +1,11 @@ - import * as React from "react"; +import Emoji from "react-emoji-render"; +import * as React from "react"; function DailyItem(props: any) { return (
-

{props.daily_text}

+

) } diff --git a/src/view/Components/Taskview/Habitsview/HabitItem.tsx b/src/view/Components/Taskview/Habitsview/HabitItem.tsx index faff665..fa397cc 100644 --- a/src/view/Components/Taskview/Habitsview/HabitItem.tsx +++ b/src/view/Components/Taskview/Habitsview/HabitItem.tsx @@ -1,4 +1,5 @@ - import * as React from "react"; +import Emoji from "react-emoji-render"; +import * as React from "react"; function HabitItem(props: any) { return ( @@ -6,7 +7,7 @@ function HabitItem(props: any) { -

{props.habit_text}

+

diff --git a/src/view/Components/Taskview/TodoItem.tsx b/src/view/Components/Taskview/TodoItem.tsx index 4adc70f..c02e230 100644 --- a/src/view/Components/Taskview/TodoItem.tsx +++ b/src/view/Components/Taskview/TodoItem.tsx @@ -1,10 +1,11 @@ - import * as React from "react"; +import { Emoji } from 'react-emoji-render'; +import * as React from "react"; function TodoItem(props: any) { return (
-

{props.todo_text}

+
) } diff --git a/src/view/Components/Taskview/Todoview/TodoItem.tsx b/src/view/Components/Taskview/Todoview/TodoItem.tsx index 4adc70f..2766dbe 100644 --- a/src/view/Components/Taskview/Todoview/TodoItem.tsx +++ b/src/view/Components/Taskview/Todoview/TodoItem.tsx @@ -1,10 +1,11 @@ - import * as React from "react"; +import Emoji from "react-emoji-render"; +import * as React from "react"; function TodoItem(props: any) { return (
-

{props.todo_text}

+

) } diff --git a/src/view/habiticaAPI.ts b/src/view/habiticaAPI.ts index 36f2b25..142a923 100644 --- a/src/view/habiticaAPI.ts +++ b/src/view/habiticaAPI.ts @@ -6,7 +6,7 @@ export async function getStats(username: string, credentials: string){ method: 'GET', headers: { "Content-Type": "application/json", - "x-client": username.concat("-testAPI"), + "x-client": "278e719e-5f9c-43b1-9dba-8b73343dc062-HabiticaSync", "x-api-user": username, "x-api-key": credentials, }, @@ -20,7 +20,20 @@ export async function scoreTask(username: string, credentials: string, taskID: s method: 'POST', headers: { "Content-Type": "application/json", - "x-client": username.concat("-testAPI"), + "x-client": "278e719e-5f9c-43b1-9dba-8b73343dc062-HabiticaSync", + "x-api-user": username, + "x-api-key": credentials, + } + }) + return(response) +} +export async function makeCronReq(username: string, credentials: string){ + const url = "https://habitica.com/api/v3/cron"; + 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, } diff --git a/styles.css b/styles.css index 680c446..b31b4a2 100644 --- a/styles.css +++ b/styles.css @@ -1,151 +1,181 @@ - -#profile-name { - font-size: x-large; - font-weight: bold; - padding-bottom: 3%; -} -.stats { - padding-bottom: 6px; -} - -.todo-item { - display: flex; - justify-content: flex-start; - 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; -} - -.habit-text { - text-align: center !important; - padding: 0px; - width: 80px; - margin-right: 20px; -} - -.habit-plus { - /* background-color: #fff; */ - border: none; - color: white; - padding: 7px 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-content: space-between; - align-items: center; - padding: 0px 0px 0; - width: 100%; - border-bottom: 1px solid #cecece; - font-family: Roboto, sans-serif; - font-weight: 50%; - font-size: 16px; - -} - -input[type=checkbox] { - margin-right: 10px; -} - -input[type=checkbox]:focus { - outline: 0; -} - -.plugin-root { - min-width: 260px; -} - -.substats { - font-size: medium; -} - -/* react-tabs internal file :wink: */ -.material-icons { - font-size: 12px !important; - padding-top: 1px; - padding-right: 2px; - -} - -.material-icons.md-18 { font-size: 18px !important; } -.material-icons.md-24 { font-size: 24px !important; } -.material-icons.md-32 { font-size: 32px !important; } -.material-icons.md-48 { font-size: 48px !important; } - - -.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: 1% 2%; - cursor: pointer; - font-size: medium; -} - -.react-tabs__tab--selected { - background: var(--interactive-accent); - color: white; - 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; -} + +#profile-name { + font-size: x-large; + font-weight: bold; + padding-bottom: 3%; +} +.stats { + padding-bottom: 6px; +} + +.todo-item { + display: flex; + justify-content: flex-start; + 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; +} + +.habit-text { + text-align: center !important; + padding: 0px; + width: 50%; + margin-right: 20px; +} + +.habit-plus { + /* background-color: #fff; */ + border: none; + color: white; + padding: 7px 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-content: space-between; + align-items: center; + padding: 0px 0px 0; + width: 100%; + border-bottom: 1px solid #cecece; + font-family: Roboto, sans-serif; + font-weight: 50%; + font-size: 16px; + +} + +input[type=checkbox] { + margin-right: 10px; +} + +input[type=checkbox]:focus { + outline: 0; +} + +.plugin-root { + min-width: 260px; +} + +.substats { + font-size: medium; +} + +/* react-tabs internal file :wink: */ +.material-icons { + font-size: 12px !important; + padding-top: 1px; + padding-right: 2px; + +} + +.material-icons.md-18 { font-size: 18px !important; } +.material-icons.md-24 { font-size: 24px !important; } +.material-icons.md-32 { font-size: 32px !important; } +.material-icons.md-48 { font-size: 48px !important; } + + +.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: 1% 2%; + cursor: pointer; + font-size: medium; +} + +.react-tabs__tab--selected { + background: var(--interactive-accent); + color: white; + 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; +} +ul li:not(.task-list-item)::before { + content: "•"; + color: transparent; + display: inline-block; + width: 1em; + margin-left: -1em; + padding: 0; + font-weight: bold; + text-shadow: 0 0 0.5em transparent; +} +body > div.app-container.is-left-sidedock-collapsed.is-right-sidedock-collapsed > div.horizontal-main-container > div > div.workspace-split.mod-horizontal.mod-right-split > div.workspace-tabs > div.workspace-leaf > div > div.view-content > div > div.cron > button { + margin: auto; + margin-bottom: 5px; +} +.cron { + display: inline-grid; + justify-content: center; + text-align: center;; + margin-top: 5px; + margin-left: 10%; + margin-right: 10%; + margin-bottom: 10px; + background-color: var(--background-secondary-alt); + border-radius: 10px; +} +#cronMessage { + margin: 20px; + margin-bottom: 10px; + color: var(--text-normal) +}