Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple fixes #257

Merged
merged 3 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/providers/quick_items_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class QuickItemsProvider extends ChangeNotifier {
void decreaseInventory(QuickItem item) {
return;
// Temporary removed items in Torn
// ignore: dead_code
if (item.inventory! > 0) {
item.inventory = item.inventory! - 1;
_saveListAfterChanges();
Expand Down
349 changes: 118 additions & 231 deletions lib/utils/js_snippets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1161,239 +1161,77 @@ String bountiesJS({
''';
}

String ocNNB({required String members}) {
String ocNNB({required String members, required int playerID}) {
return '''
// Credits: some functions and logic thanks to Torn Tools

(function() {

var data = $members;

function loadNNB () {

var iw = window.innerWidth;

// Avoid adding NNB twice
var savedFound = document.querySelector(".pdaNNBListener") !== null;
if (!savedFound) {
var save = document.querySelector(".faction-crimes-wrap");
save.classList.add("pdaNNBListener");
console.log("Torn PDA: adding NNB!");
} else {
console.log("PDA NNB found, returning");
return;
}

// Add style nnb title
function addStyle(styleString) {
const style = document.createElement('style');
style.textContent = styleString;
document.head.append(style);
((members, playerID) => {
const waitForOCs = (maxCount = 100) =>
new Promise((resolve, reject) => {
const intID = setInterval(() => {
const ocRows = \$("ul.crimes-list > li");
if (ocRows.length) {
clearInterval(intID);
resolve(ocRows);
} else {
if (maxCount-- <= 0) {
clearInterval(intID);
reject(new Error("Could not find member rows"));
}
}
}, 100);
});

const handleOCRows = (ocRows) => {
ocRows.each((_, row) => {
const table = \$(row).find(".details-wrap:not(.pda-modified)");
if (!table.length) return // No new table to update
const shouldHighlightRow = handleOCTable(table);
if (shouldHighlightRow) \$(row).find("> ul.item").addClass("pda-highlight-row");
});
};

const handleOCTable = (table) => {
let shouldHighlightRow = false;
table.addClass("pda-modified");
table.find("> ul > li > ul:not(.pda-table-row)").each((i, row) => {
\$(row).addClass("pda-table-row");
if (i === 0)
return \$("<li/>", { text: "NNB" }).insertBefore(
\$(row).find("li.stat")
);
const id = \$(row)
.find("a[href*='profiles.php?XID=']")
.attr("href")
?.match(/XID=(\\d+)/)?.[1];
if (!id) return console.error("Missing ID for row", row);
if (id === playerID.toString()) shouldHighlightRow = true;
\$("<li/>", { text: members[id] || "unk" }).insertBefore(
\$(row).find("li.stat")
);
});
return shouldHighlightRow;
};

const addStyles = () => {
const styles = `
.pda-table-row {
display: grid;
grid-template-columns: 1fr 3rem 3rem 5rem;
}
.pda-table-row > * {
width: unset !important;
}
.pda-table-row > *:not(.member) {
text-align: center !important;
}

addStyle(
`.pda-nnb-title {
text-align: right;
width: 30px;
}`
);

addStyle(
`.pda-nnb-value {
width: 30px;
}`
);

addStyle(
`.member.pda-modified-top-narrow {
width: 140px !important;
}`
);

addStyle(
`.member.pda-modified-top-wide {
width: 200px !important;
}`
);

addStyle(
`.member.pda-modified-bottom-narrow {
width: 80px !important;
}`
);

addStyle(
`.member.pda-modified-bottom-wide {
width: 140px !important;
}`
);

addStyle(
`.level.pda-modified-top-narrow {
width: 15px !important;
}`
);

addStyle(
`.level.pda-modified-top-wide {
width: 25px !important;
}`
);

addStyle(
`.level.pda-modified-bottom-narrow {
width: 15px !important;
}`
);

addStyle(
`.level.pda-modified-bottom-wide {
width: 25px !important;
}`
);

addStyle(
`.offences.pda-modified {
width: 50px !important;
}`
);

addStyle(
`.act.pda-modified {
width: 29px !important;
}`
);

addStyle(
`.stat.pda-modified {
width: 50px !important;
}`
);


function createNerveTitle () {
var newDiv = document.createElement("li");
var newContent = document.createTextNode("NNB");
newDiv.className = "pda-nnb-title";
newDiv.appendChild(newContent);
return newDiv;
}

function createNerveValue (value) {
var newDiv = document.createElement("li");
var newContent = document.createTextNode(value);
newDiv.className = "pda-nnb-value";
newDiv.appendChild(newContent);
return newDiv;
}

var member = document.querySelectorAll('.member');
for (var m of member) {
// Crimes scheduled
var row = m.closest(".organize-wrap .crimes-list .details-list > li > ul");
if (row !== null)
{
row.querySelectorAll(`.offences`).forEach((element) => element.classList.add("pda-modified"));

row.querySelectorAll(`.level`).forEach((element) => element.classList.add("pda-modified"));
if (iw < 785) {
row.querySelectorAll(`.level`).forEach((element) => element.classList.add("pda-modified-top-narrow"));
} else {
row.querySelectorAll(`.level`).forEach((element) => element.classList.add("pda-modified-top-wide"));
}

if (iw < 387) {
row.querySelectorAll(`.member`).forEach((element) => element.classList.add("pda-modified-top-narrow"));
} else {
row.querySelectorAll(`.member`).forEach((element) => element.classList.add("pda-modified-top-wide"));
}

row.querySelectorAll(`.stat`).forEach((element) => element.classList.add("pda-modified"));

let stat = row.querySelector(".stat");
if (stat === null) continue;

if (row.classList.contains("title")) {
stat.parentElement.insertBefore(
createNerveTitle(),
stat
);
continue;
}

const id = row.querySelector(".h").getAttribute("href").split("XID=")[1];

var found = false;
for (const [key, value] of Object.entries(data)) {
if (id === key) {
stat.insertAdjacentElement("beforebegin", createNerveValue(value));
found = true;
continue;
}
}
if (!found) {
stat.insertAdjacentElement("beforebegin", createNerveValue("unk"));
}
continue;
}


// Crimes available
var row = m.closest(".plans-list .item");
if (row !== null) {
row.querySelectorAll(`.offences`).forEach((element) => element.classList.add("pda-modified"));

row.querySelectorAll(`.level`).forEach((element) => element.classList.add("pda-modified"));
if (iw < 785) {
row.querySelectorAll(`.level`).forEach((element) => element.classList.add("pda-modified-bottom-narrow"));
} else {
row.querySelectorAll(`.level`).forEach((element) => element.classList.add("pda-modified-bottom-wide"));
}

if (iw < 387) {
row.querySelectorAll(`.member`).forEach((element) => element.classList.add("pda-modified-bottom-narrow"));
} else {
row.querySelectorAll(`.member`).forEach((element) => element.classList.add("pda-modified-bottom-wide"));
}

row.querySelectorAll(`.act`).forEach((element) => element.classList.add("pda-modified"));

let act = row.querySelector(".act");
if (act === null) continue;

if (row.classList.contains("title")) {
act.parentElement.insertBefore(
createNerveTitle(),
act
);
continue;
}

const id = row.querySelector(".h").getAttribute("href").split("XID=")[1];

var found = false;
for (const [key, value] of Object.entries(data)) {
if (id === key) {
act.insertAdjacentElement("beforebegin", createNerveValue(value));
found = true;
continue;
}
}
if (!found) {
act.insertAdjacentElement("beforebegin", createNerveValue("unk"));
}
}
}
}

let waitForOCAndRun = setInterval(() => {
if (document.querySelector(".faction-crimes-wrap")) {
loadNNB();
return clearInterval(waitForOCAndRun);
}
}, 300);

})();
.pda-highlight-row {
background-color: #F0F7 !important;
}
`;
\$("<style/>", { text: styles }).appendTo("head");
};
addStyles();
waitForOCs().then(handleOCRows).catch(console.trace);
})($members, $playerID);
''';
}

Expand Down Expand Up @@ -1466,3 +1304,52 @@ String greasyForkMockVM(String scripts) {
})($scripts);
""";
}

String ageToWordsOnProfile() {
return r"""
(() => {
const waitForContainer = (maxCount = 100) =>
new Promise((resolve) => {
const intID = setInterval(() => {
const container = $("div.age");
if (container.length) {
clearInterval(intID);
resolve(container);
} else if (maxCount-- <= 0) {
clearInterval(intID);
resolve(null);
}
}, 100);
});

const modifyTextToAge = (container) => {
const ageString = generateAgeString(container);
container
.find("div.box-name")
.text(ageString)
.css("margin", "8px 0 0 0")
.appendTo(container);
};

const generateAgeString = (container) => {
const el = container.find("ul.box-value");
const age = parseInt(el.text());

const current = new Date();
const signup = new Date(current - age * 24 * 60 * 60 * 1000);
const diffDate = new Date(current - signup);
const years = diffDate.getUTCFullYear() - 1970,
months = diffDate.getUTCMonth(),
days = diffDate.getUTCDate() - 1;

// yes this is dirty, but not incorrect....
let ageString = `${days} days`;
if (months) ageString = `${months} months, ${ageString}`;
if (years) ageString = `${years} years, ${ageString}`;
return ageString;
};

waitForContainer().then(modifyTextToAge);
})();
""";
}
7 changes: 6 additions & 1 deletion lib/widgets/webviews/webview_full.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2390,6 +2390,7 @@ class WebViewFullState extends State<WebViewFull> with WidgetsBindingObserver {
_assessBazaarOwn(document);
_assessBazaarOthers(document);
_assessBarsRedirect(document);
_assessProfileAgeToWords();
}

Future _assessSectionsWithWidgets() async {
Expand Down Expand Up @@ -3661,6 +3662,10 @@ class WebViewFullState extends State<WebViewFull> with WidgetsBindingObserver {
}
}

void _assessProfileAgeToWords() {
if (_currentUrl.contains("www.torn.com/profiles.php?")) webView?.evaluateJavascript(source: ageToWordsOnProfile());
}

// ASSESS PROFILES
Future _assessProfileAttack({dom.Document? document, String pageTitle = ""}) async {
if (mounted) {
Expand Down Expand Up @@ -4151,7 +4156,7 @@ class WebViewFullState extends State<WebViewFull> with WidgetsBindingObserver {
// On iOS, when using the new menu icon for OC, the html doc does not respond for some reason
// We just wait a second and then add the script (should not be noticeable)
await Future.delayed(const Duration(milliseconds: 1000));
webView!.evaluateJavascript(source: ocNNB(members: membersString));
webView!.evaluateJavascript(source: ocNNB(members: membersString, playerID: _u.playerId));
} catch (e) {
BotToast.showText(
text: "Could not load NNB from $_ocSource: $e",
Expand Down