Skip to content

Commit

Permalink
Merge branch 'release/0.4.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
HarmlessHarm committed Feb 24, 2023
2 parents bf3f290 + 716a2cd commit bfd05ce
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 26 deletions.
8 changes: 8 additions & 0 deletions css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,14 @@ ul.characters li .character .avatar {
-moz-box-shadow: var(--drop-shadow);
position: relative;
}
ul.characters li .character .avatar .default-avatar {
text-align: center;
font-size: 24px;
line-height: 50px;
width: 50px;
margin-top: 1px;
color: var(--neutral-4);
}
ul.characters li .character .avatar .level {
position: absolute;
height: 1.5rem;
Expand Down
3 changes: 2 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ <h2>
<li>Open this extension</li>
<li>Click the sync button</li>
</ol>
<a href="https://dicecloud.com/character-list" target="_blank" rel="noopener" class="block btn w-full">Go to Dice Cloud</a>
<a href="https://dicecloud.com/character-list" target="_blank" rel="noopener" class="block btn w-full mb-1">Go to Dice Cloud</a>
<a href="https://v1.dicecloud.com/characterList" target="_blank" rel="noopener" class="block neutral-4 btn btn-clear w-full">Go to Dice Cloud v1</a>
</div>
</div>

Expand Down
7 changes: 4 additions & 3 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"manifest_version": 3,
"author": "Harm Manders & Key Roos",
"name": "D&D Character Sync",
"description": "Syncs character data across D&D apps",
"version": "0.3.0",
"description": "Store character sheets from different D&D apps",
"version": "0.4.0",
"background": {
"service_worker": "background.js",
"type": "module"
Expand Down Expand Up @@ -41,6 +41,7 @@
"*://*.harmlesskey.com/content/players/*",
"*://harmlesskey.com/content/characters/*",
"*://*.harmlesskey.com/content/characters/*",
"*://dicecloud.com/character/*"
"*://dicecloud.com/character/*",
"*://v1.dicecloud.com/character/*"
]
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dnd-character-sync",
"version": "0.3.0",
"version": "0.4.0",
"description": "A Chrome extension that grabs your Dungeons & Dragons character's stats from various platforms like D&D Beyond and Harmless Key.",
"scripts": {
"gulp": "gulp"
Expand Down
2 changes: 1 addition & 1 deletion popup/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const syncCharacter = async (e) => {
// Remove the sync button from my-characters overview
const footer = document.querySelector("#my-characters .footer");
const btn = footer.querySelector(".sync-character")
footer.removeChild(btn);
footer?.removeChild(btn);
};

/**
Expand Down
3 changes: 3 additions & 0 deletions popup/my-characters.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ const renderCharacters = async (list) => {

const image = character.avatar ? character.avatar : character.source === "HarmlessKey" ? "../assets/images/logo_harmless_key_icon.png" : "";
avatar.setAttribute("style", `background-image: url(${image});`);
if (image === "") {
avatar.innerHTML = '<i class="far fa-helmet-battle default-avatar"></i>';
}

if(character.level) {
const level = document.createElement("div");
Expand Down
75 changes: 62 additions & 13 deletions src/dicecloud/character.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ class DiceCloudCharacter extends Character {
}
this.url = window.location.href;

this.isV1 = false;
if (/v1\.dicecloud\.com/.test(this.url)) {
this.isV1 = true;
}

this.setName(this.parseName());

this.setAvatar(this.parseAvatar());
Expand All @@ -31,17 +36,32 @@ class DiceCloudCharacter extends Character {
}

parseName() {
const parsedName = document.querySelector('.v-toolbar__title')?.textContent
return parsedName.trim() ?? null;
let parsedName = null;
if (this.isV1) {
parsedName = document.querySelector('.character-name')?.textContent;
}
else {
parsedName = document.querySelector('.v-toolbar__title')?.textContent
}
return parsedName?.trim() ?? null;
}


parseAvatar() {
if (this.isV1) {
return null;
}
const avatar_url = document.querySelector('.v-avatar img')?.src;
return avatar_url ?? null;
}

async parseLevel() {
if (this.isV1) {
const level_v1 = document.querySelector('[name="journal"] .containerName')?.textContent.trim();
const level = parseInt(level_v1.replace(/\D*/, ""))
return level ?? null;

}
const container = document.querySelector('.class-details .v-card__title')
if (!container) {
document.querySelectorAll('.v-tab')[6].click()
Expand All @@ -51,45 +71,74 @@ class DiceCloudCharacter extends Character {

const level_str = document.querySelector('.class-details .v-card__title').textContent.trim()
const level = parseInt(level_str.replace(/\D*/, ""));
console.log("in timeout", level);
return level ?? null;
}

parseStat(stat) {
const containers = document.querySelectorAll('.stat');
let container_selector = '.stat'
let stat_name_selector = '.v-card .layout .name'
let stat_value_selector = '.v-card .layout .value'
if (this.isV1) {
container_selector = '.stat-card'
stat_name_selector = '.paper-font-subhead'
stat_value_selector = '.numbers'
}
let containers = document.querySelectorAll(container_selector);

let parsedStat;
for(const container of containers) {
const name = container?.querySelector('.v-card .layout .name')?.textContent;
const name = container?.querySelector(stat_name_selector)?.textContent;
if(name.trim() === stat) {
parsedStat = container?.querySelector('.v-card .layout .value')?.textContent;
parsedStat = container?.querySelector(stat_value_selector)?.textContent;
return parseInt(parsedStat) ?? null;
}
}
return parseInt(parsedStat) ?? null;
return null;
}

parseCheck(check) {
const containers = document.querySelectorAll('.check');
let container_selector = '.check'
let stat_name_selector = '.v-card .layout .name'
let stat_value_selector = '.v-card .layout div .v-btn .v-btn__content .value'
if (this.isV1) {
container_selector = '.stat-card'
stat_name_selector = '.paper-font-subhead'
stat_value_selector = '.numbers div'
}

const containers = document.querySelectorAll(container_selector);

let parsedStat;
for(const container of containers) {
const name = container?.querySelector('.v-card .layout .name')?.textContent;
const name = container?.querySelector(stat_name_selector)?.textContent;
if(name.trim() === check) {
parsedStat = container?.querySelector('.v-card .layout div .v-btn .v-btn__content .value')?.textContent;
parsedStat = container?.querySelector(stat_value_selector)?.textContent;
return parseInt(parsedStat) ?? null;
}
}
return parseInt(parsedStat) ?? null;
return null;
}

parseMaxHitPoints() {
if (this.isV1) {
const hpField = document.querySelector('#hitPointSlider #input-1')
const Hp = hpField.getAttribute('max')
return parseInt(Hp) ?? null;
}
const Hp = document.querySelector('.health-bar .bar .value')?.textContent;
const parsedHp = Hp ? parseInt(Hp.split("/")[1]) : null;
return parsedHp ?? null;
}

parseAbilityScore(n) {
const container = document.querySelectorAll('.ability-scores .v-list .ability-list-tile')[n];
const parsedScore = container?.querySelector('.v-list-item__action div .v-btn .v-btn__content div .value span')?.textContent;
let container_selector = '.ability-scores .v-list .ability-list-tile'
let stat_selector = '.v-list-item__action div .v-btn .v-btn__content div .value span'
if (this.isV1) {
container_selector = '.stats .ability-mini-card'
stat_selector = '.numbers .stat'
}
const container = document.querySelectorAll(container_selector)[n];
const parsedScore = container?.querySelector(stat_selector)?.textContent;
return parseInt(parsedScore) ?? 0;
}
}
28 changes: 23 additions & 5 deletions src/dndbeyond/character.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class DndBeyondCharacter extends Character {

this.setLevel(this.parseLevel());

this.setXp(this.parseXp());

this.setArmorClass(this.parseArmorClass());

this.setMaxHitPoints(this.parseMaxHitPoints())
Expand All @@ -26,7 +28,7 @@ class DndBeyondCharacter extends Character {
["strength", "dexterity", "constitution", "intelligence", "wisdom", "charisma"].forEach((ability, i) => {
this.setAbilityScore(ability, this.parseAbilityScore(i));
});

-
console.log("updated character to:", this);
}

Expand All @@ -39,16 +41,32 @@ class DndBeyondCharacter extends Character {
parseAvatar() {
const avatar_style = document.querySelector('.ddbc-character-avatar__portrait')?.style.backgroundImage;
const url_regex = /url\([\"\'\`](.+)[\"\'\`]\)/
const avatar_url = avatar_style?.match(url_regex)[1]
return avatar_url ?? null;
const avatar_match = avatar_style?.match(url_regex)

return avatar_match ? avatar_match[1] : "https://www.dndbeyond.com/Content/Skins/Waterdeep/images/characters/default-avatar-builder.png";
}

parseLevel() {
const level = document.querySelector('.ddbc-character-progression-summary__level')?.textContent;
const parsedLevel = level.match(/\d+/).join();
let level = document.querySelector('.ddbc-character-progression-summary__level')?.textContent;
if (!level) {
// Non Milestone leveling
const xp_container = document.querySelector('.ddbc-character-progression-summary__xp-bar');
level = xp_container?.querySelector('.ddbc-xp-bar__item--cur .ddbc-xp-bar__label')?.textContent;
}

const parsedLevel = level?.match(/\d+/).join();
return parseInt(parsedLevel) ?? null;
}

parseXp() {
const xp_container = document.querySelector('.ddbc-character-progression-summary__xp-bar');
if (!xp_container) {
return null;
}
const xp_data = xp_container.querySelector('.ddbc-character-progression-summary__xp-data')?.textContent?.split('/');
return xp_data ? parseInt(xp_data[0].trim()) : null;
}

parseArmorClass() {
if (isMobile()) {
const armor_class = document.querySelector('.ct-combat-mobile__extra--ac .ct-combat-mobile__extra-value')?.textContent;
Expand Down
8 changes: 8 additions & 0 deletions src/models/character.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class Character {
this.name = null;
this.avatar = null;
this.level = null;
this.xp = null;
this.armor_class = 0;
this.hit_points = 0;
this.max_hit_points = 0;
Expand Down Expand Up @@ -46,6 +47,13 @@ class Character {
setLevel(level) {
this.level = level;
}

getXp() {
return this.xp
}
setXp(xp) {
this.xp = xp;
}

getArmorClass() {
return this.armor_class
Expand Down

0 comments on commit bfd05ce

Please sign in to comment.