Oladon |
26 people marked this as a favorite. |
Reposting this since most of you probably don't read Website Feedback.
I've created a browser extension for Chrome and Firefox containing some useful features for those of us who participate in PbPs here. Current tools are: Arranger (rearranges the user campaigns page to be more readable [with less scrolling]), User Blacklist (greys out or hides posts by certain users), and Highlighter (highlights the "(x new)" links on campaign pages).
Firefox version is available here or here. (At time of posting, both links are on version 1.25, but future versions will be available at the second link first due to Firefox's review process.)
Google Chrome version is available here.
If you use Opera (or another browser that lets you add user scripts), you can still have the Arranger and Highlighter tools by following the "Opera" installation instructions on Github.
Please let me know if you have any questions, requests, or feedback!
John Woodford |
91 users right now across both versions. Right now there are no reported bugs, which is quite satisfying.
I've got a few ideas for next features, but I'm always open to hearing what the users would like to see!
The only bug I've run across so far (in the sense of an unanticipated formatting issue, not something that nukes my browser and salts the earth around the crater) is that occasionally instead of the usual 4x4 layout of campaigns and highlighted new post lists I get rows of at most seven each, with no highlighting. It stays that way through refreshing or navigating away and coming back, but not through browser shutdown and restart. Using Firefox; happens maybe once every week or two, and has continued to happen over the past couple of Firefox updates.
Oladon |
So since I'm new and looking to get into doing PBP, how does this extension help me?
If you're only in one or two games (or not in any), you'll likely not need the formatting/highlighter functionality. However, it's likely that you'll still find the Blacklist feature handy, as it will let you not see (or de-emphasize) posts from people you don't want to game with. This can be especially useful for recognizing that someone else is active in a recruitment you're in, so that you know going into it that they may get into the game.
Oladon wrote:The only bug I've run across so far (in the sense of an unanticipated formatting issue, not something that nukes my browser and salts the earth around the crater) is that occasionally instead of the usual 4x4 layout of campaigns and highlighted new post lists I get rows of at most seven each, with no highlighting. It stays that way through refreshing or navigating away and coming back, but not through browser shutdown and restart. Using Firefox; happens maybe once every week or two, and has continued to happen over the past couple of Firefox updates.91 users right now across both versions. Right now there are no reported bugs, which is quite satisfying.
I've got a few ideas for next features, but I'm always open to hearing what the users would like to see!
John, when you notice this, have you happened to check the URL in your URL bar? Occasionally Paizo will redirect you to a URL that isn't of the format "paizo.com/people/yourname", and is instead a long string of semi-nonsense. In cases like that, you often have to navigate away from the Campaigns page and then go back to it to try to get the URL "back to normal".
Oladon |
5 people marked this as a favorite. |
Big news, my friends. You may have already noticed, but I've just released a...
New (Chrome) Extension Version!
(Don't worry, Firefox users, I haven't forgotten you... jump down and I'll explain.)
This version contains a few bug fixes, but the primary purpose of the release is to give you a new feature... namely, live campaign chat. If you have chat enabled (it's enabled by default, and why in the world would you want to disable such an awesome feature?), you'll now see a little chat icon beside each campaign on your campaigns overview page. In addition, when you enter a thread in a campaign you're part of, you'll see a little chat icon beside the campaign name as well as a minimized chat box in the bottom-right corner of your screen. That's campaign chat.
You'll need to visit your campaigns page first to have the chat show up in the individual threads.
At the urging of more than one person, I've also set up a Patreon profile so that those who wish to do so may support my work on this and other neat projects.
There are some things you may be wondering at this point...
How does it work?
Clicking on the chat icon beside a campaign will show the chat window for that campaign. Clicking it again will minimize the chat window. If you get a new message for a campaign while the chat window is hidden, minimized, or displaying a different campaign, you'll see a "new message" icon beside the campaign with a new message.
You can click on the roster icon in the chat window toolbar to view a list of who's currently in the room. Just click the "back to chat" button or click on one of the chat icons beside a campaign name to return to the chat.
The little lock icon is for moving around the chat window. You can click it to unlock the window position, drag the window to the desired position, and then click it again to lock (save) the new position. It'll be there from then on!
Can I change the alias I chat as for a thread?
Not currently. See the question "What about feature _________?" below.
When is the Firefox version coming?
Soon... it turned out to be significantly more difficult to implement this feature in Firefox than it is in Chrome, and most of my users use Chrome... so they got it first. Don't worry, though: I use Firefox, so I'll definitely be working on bringing this feature to Firefox as soon as I can.
Are conversations saved? Where? Does Oladon have access to them?
All the messages you receive are stored locally on your computer... no logging (saving of messages) is done on the chat server, and no, I don't have access to the messages saved on your computer.
What if I want to look at old messages?
Right now there's not an easy way to do that; sorry. If you really want to look at old messages, you can go to chrome://extensions, enable "Developer Mode", click on "background page" under the PCT extension, then click on the Resources tab, then click on IndexedDB and browse to the room (campaign) for which you'd like to see the history.
I've got plans to add a more user-friendly log viewing system, but I felt it was worth postponing that to get this feature out to you all sooner.
What if I'm behind a firewall?
The chat feature may or may not work from behind a firewall. Some firewalls block access to the chat server, while others might block the port used by chat (5280).
What about feature ________?
Is there a feature you think I should add? Shoot me a PM or message me on Patreon and let me know! I promise I'll at least think about it, if I haven't already. I have a ton of ideas I'd like to implement to improve the campaign chat... I'm just limited by time.
What if something goes wrong?
As always, feel free to contact me if anything goes wrong, and I'll do my best to get it sorted out.
DM Khel |
As an early tester of this, I'll say the chat feature is really cool! In the past, I have found that chatting with others in my PbP games while on Google maps, Roll20 or other spots has been a good way to get to know people a bit better and make the game a bit more dynamic at times. And now I can do that from right here on the Paizo boards!
Papa-DRB |
Verified 1.1.1 and Chat Enabled checked.
Doesn't work for me either in Chrome Version 43.0.2357.134 m
I do have some other extensions. Is there anything that you know of that I might have to disable?
Adblock Pro 3.1
The free adblock tool for Chrome: Blocks annoying video ads on YouTube, Facebook ads, banners and much more.
Details Options
Allow in incognito
Enabled
Bookmarks Menu 3.4.15
Shows bookmarks menu. Works with Chrome and Google bookmarks.
Details Options
Allow in incognito
Enabled
Dashlane 3.2.6.21047
Password Manager and Secure Digital Wallet
Details
Allow in incognito
Allow access to file URLs
Enabled
FlashControl 6.15.7
A flashblock tool that provides more control over Flash content.
Details Options
Allow in incognito
Enabled
Google Docs 0.9
Create and edit documents
Details
Allow in incognito
Enabled
Google Sheets 1.1
Create and edit spreadsheets
Details
Allow in incognito
Enabled
Google Slides 0.9
Create and edit presentations
Details
Allow in incognito
Enabled
Hangouts 2015.302.433.1
Hangouts brings conversations to life with photos, emoji, and even group video calls for free.
Details Options
Allow in incognito
Enabled
Paizo Campaign Tools 1.1.1
A collection of tools for enhancing the Paizo PbP experience.
Details Options
Allow in incognito
Enabled
Stylish 1.3.1
Restyle the web with Stylish, a user styles manager. Stylish lets you easily install themes and skins for many popular sites.
Details Options
Allow in incognito
Allow access to file URLs
Enabled
Application Launcher for Drive (by Google) 3.2
Open Drive files directly from your browser in compatible applications installed on your computer.
Details
-- david
Oladon |
Not that I know of... tell you what, though. Open up Chrome and open a new tab. Hit F12, and click on "Console" there, then load your campaigns page normally, but watch for any red text (errors) in the console you brought up with F12.
If you see any, copy 'em and send them to me in a PM. If you don't see any, we'll have to go to stage 2...
Walter das Sombras |
I'm also missing something, it seems, cause I don't see anything... There are no highlights, nor chat, nor anything. Adblock is off, and the tools are active.
Any guesses?
In my case, all I see is the X from the blacklist, and nothing aside from that. The My Campaigns tab gives me the following alert (in yellow):
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
In the threads I open there is the following error (in red):
Error in event handler for (unknown): SyntaxError: Unexpected token u
at chrome-extension://ibfgfbafipmhmjohndaekilkkldeahgd/content/pct.js:265:31ha ndler @ extensions::uncaught_exception_handler:8
Me'mori |
No chat icons either.
I'm running:
Adblock Plus
Ghostery
HTTPS Anywhere
Blur
DuckDuckGo
Track Me Not
Privacy Badger
Pixelblock
EDIT: Correction- I see the blacklist icons, but no chat bubbles.
Red text: "Error in event handler for (unknown): SyntaxError: Unexpected token u
at chrome-extension://ibfgfbafipmhmjohndaekilkkldeahgd/content/pct.js:265:31"
Oladon |
Thanks for the help, guys. That's really, really weird, and I can't seem to replicate the issue on my end.
Walter, are you using Adblock? So far that's the only similarity I'm seeing between you all's setup.
Is there any more text associated with the error you two posted? There might be a little drop-down that would give you more...
Walter das Sombras |
Walter das Sombras |
if (!campaigns || campaigns.length == 0) {
storedCampaigns = response.storage.campaigns;
storedCampaignsArray = JSON.parse(storedCampaigns);
currentCampaign = storedCampaignsArray.find(function(campaign) {
return currentHref.indexOf(campaign.url) >= 0;
});
}
That lines highlights the one that has the JSON.parse
Oladon |
Okay, I've managed to replicate the error, but I can only make it happen when I go to a thread page without having first visited my root user campaigns page; have you guys all done that?
Walter's would be http://paizo.com/people/WalterDasSombras/campaigns, Me'mori's would be http://paizo.com/people/Memori/campaigns, DRB's would be http://paizo.com/people/PapaDRB/campaigns, etc.
Could you try that and then reload the threads you're trying to chat in and let me know if it works? In the meantime, I'll try to make it a bit clearer that that's what's happening. :)
Walter das Sombras |
The highlights appear at the root user campaign page, but not in the My Campaigns. The blacklist is ok, but no sign of the rearrange function nor the chat. I get the same error Papa-DRB is getting in a game thread:
Error in event handler for (unknown): SyntaxError: Unexpected token u
at chrome-extension://ibfgfbafipmhmjohndaekilkkldeahgd/content/pct.js:265:31
handler @ extensions::uncaught_exception_handler:8
Clicking on it I have this message:
(function() {
const PCT_GREYSCALE = "pct-greyscale";
const PCT_DISPLAYNONE = "pct-display-none";//var pctBlacklist = window.pctBlacklist;
var pctChat = window.pctChat;var username = pctChat.getUsername() || undefined;
if (!Array.prototype.find) {
Array.prototype.find = function(predicate) {
if (this == null) {
throw new TypeError('Array.prototype.find called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return value;
}
}
return undefined;
};
}/* Arranger Code */
function getCampaigns() {
var myCampaigns = [],
activeCampaigns = document.querySelectorAll('table > tbody > tr > td > table > tbody > tr > td > blockquote > h3 > a');
for (var i=0; i<activeCampaigns.length; i++) {
myCampaigns.push(activeCampaigns[i].parentNode.parentNode.parentNode);
}
return myCampaigns;
}function campaignsToArray(campaigns) {
var campaignsArray = campaigns.map( function(campaign, index, array) {
var currentCampaign = campaign;
var userDM = (currentCampaign.querySelector('blockquote > p[class=tiny] > b').textContent.trim() == "GameMaster");
var title = currentCampaign.querySelector('blockquote > h3 > a[title]').title;
var URL = currentCampaign.querySelector('blockquote > h3 > a[title]').href;
var userAliases = currentCampaign.querySelectorAll('p.tiny > b > a');
var userAliasesArray = [];for (var alias of [].slice.call(userAliases)) {
userAliasesArray.push({ name: alias.textContent.trim(),
url: alias.href });
}
if (!userAliases || userAliases.length <= 0) {
userAliasesArray = username && [{ name: username }];
}var campaignObject = { title: title,
url: URL,
user_dm: userDM,
user_aliases: userAliasesArray
};return campaignObject;
});return campaignsArray;
}function saveCampaigns(campaigns) {
var activeCampaigns = JSON.stringify(campaigns);
chrome.runtime.sendMessage({ storage: "campaigns", value: activeCampaigns});
}function arrangeCampaigns(campaigns) {
if (campaigns.length > 8) {
var firstCampaign = campaigns[0],
firstColumn = firstCampaign.parentNode.parentNode;for (var i=0; i<campaigns.length; i++) {
var row = document.createElement('tr');
row.appendChild(campaigns[i]);
firstColumn.appendChild(row);
}var rows = firstColumn.querySelectorAll('tr');
for (var i=0; i<rows.length; i++) {
if (rows[i].children.length === 0) {
rows[i].parentNode.removeChild(rows[i]);
}
}var secondColumn = firstColumn.parentNode.parentNode.nextSibling.nextSibling;
if (secondColumn) {
secondColumn.parentNode.removeChild(secondColumn);
}
}
}/* Blacklist Code */
function getPosts() {
var myPosts = [ ],
allPosts = document.querySelectorAll('itemscope');
for (var i = 0; i < allPosts.length; i++) {
myPosts.push(allPosts[i]);
}
return myPosts;
}function blacklistPosts(blacklistPrefs) {
if (checkBlacklistPrefs(blacklistPrefs) == "false") { return; }var blacklist = blacklistToArray(blacklistPrefs.blacklist);
var posts = getPosts();
var blacklistMethod = blacklistPrefs.blacklistMethod;for (var i=0; i<posts.length; i++) {
var postDiv = posts[i].querySelector('div');
var nameAndTitle = posts[i].querySelector('span > a[title]');
var name = nameAndTitle.textContent.trim();
var title = nameAndTitle.title;
var blacklisted = false;if (blacklist) {
for (var j=0; j<blacklist.length; j++) {
if ((name.indexOf(blacklist[j]) >= 0) ||
(title.indexOf(blacklist[j]) >= 0)) {
blacklisted = blacklist[j];
if (blacklistMethod == PCT_GREYSCALE) {
if (postDiv.getAttribute("class").indexOf("pct-greyscale") < 0) {
postDiv.setAttribute("class", postDiv.getAttribute("class") + " pct-greyscale");
}
} else if (blacklistMethod == PCT_DISPLAYNONE) {
if (postDiv.style.display != "none") {
postDiv.style.display = "none";
}
}
break;
}
}
}if (blacklisted == false) {
if (blacklistMethod == PCT_GREYSCALE) {
postDiv.setAttribute("class", postDiv.getAttribute("class").replace(" pct-greyscale", ""));
} else if (blacklistMethod == PCT_DISPLAYNONE) {
postDiv.style.display = "";
}
}
addSpan(nameAndTitle, blacklisted);
}
}function addSpan(nameNode, blacklistedUser) {
var oldLink = nameNode.parentNode.parentNode.querySelector("a#pct-link"),
rootUser = getRootUser(nameNode.title),
newSpan, newLink;if (oldLink) {
newLink = oldLink;
newSpan = oldLink.firstChild;
} else {
newSpan = document.createElement("span");
newLink = document.createElement("a");newLink.id = "pct-link";
newLink.appendChild(newSpan);
nameNode.parentNode.parentNode.appendChild(newLink);
}if (blacklistedUser) {
newSpan.className = "pct-icon pct-allowedIcon";
newLink.setAttribute("title", "Remove " + blacklistedUser + " from the Blacklist");
newLink.setAttribute("action", "remove");
newLink.setAttribute("username", blacklistedUser);
newLink.setAttribute("href", 'javascript:;');
newLink.removeEventListener("click", updateBlacklist);
newLink.addEventListener("click", updateBlacklist);
} else {
newSpan.className = "pct-icon pct-notAllowedIcon pct-greyscale";
newLink.setAttribute("title", "Blacklist " + rootUser);
newLink.setAttribute("action", "add");
newLink.setAttribute("username", rootUser);
newLink.setAttribute("href", 'javascript:;');
newLink.removeEventListener("click", updateBlacklist);
newLink.addEventListener("click", updateBlacklist);
}
}function getRootUser(title) {
possibleUsers = title.match("(Alias of (.+?)|Pathfinder Society character of (.+?)|(.+?))( aka .*|\$)");
/* Array.prototype.forEach.call(possibleUsers, function(thing) { dump(thing + "\n"); }) */
switch (true) {
case typeof possibleUsers[4] !== 'undefined':
return possibleUsers[4];
case typeof possibleUsers[2] !== 'undefined':
return possibleUsers[2];
case typeof possibleUsers[3] !== 'undefined':
return possibleUsers[3];
}
}function checkBlacklistPrefs(blacklistPrefs) {
var blacklistNormal = blacklistPrefs.blacklistNormal,
blacklistRecruit = blacklistPrefs.blacklistRecruit,
blacklistOOC = blacklistPrefs.blacklistOOC,
blacklistIC = blacklistPrefs.blacklistIC;return (((document.location.href.indexOf("/threads/") >= 0) && blacklistNormal) ||
((document.location.href.indexOf("/recruiting") >= 0) && blacklistRecruit) ||
((document.location.href.indexOf("/discussion") >= 0) && blacklistOOC) ||
((document.location.href.indexOf("/gameplay") >= 0) && blacklistIC));
}function updateBlacklist(evt) {
pctBlacklist.blackListener(evt, function() {
chrome.runtime.sendMessage({storage: ['blacklistNormal', 'blacklistRecruit', 'blacklistOOC', 'blacklistIC', 'blacklistMethod', 'blacklist']}, function(response) {
var blacklistPrefs = response.storage;
blacklistPosts(blacklistPrefs);
});
});
}/* Highlighter Code */
function highlightNew(highlightColor) {
var newLinks = document.querySelectorAll('table > tbody > tr > td > table > tbody > tr > td > blockquote > ul > li > span.tiny > span > a:not([title^="Stop"])');for (var i=0; i<newLinks.length; i++) {
newLinks[i].style.backgroundColor=highlightColor;
}
}var campaigns = getCampaigns();
chrome.runtime.sendMessage({storage: 'useArranger'}, function(response) {
var useArranger = response.storage;if ((useArranger == "true") && (document.location.href.indexOf("/campaigns") >= 0)) {
arrangeCampaigns(campaigns);
}
});chrome.runtime.sendMessage({storage: ['useBlacklist', 'blacklistNormal', 'blacklistRecruit', 'blacklistOOC', 'blacklistIC', 'blacklistMethod', 'blacklist']}, function(response) {
var useBlacklist = response.storage.useBlacklist,
blacklistMethod = response.storage.blacklistMethod,
blacklistPrefs = response.storage;if ((useBlacklist == "true") && (checkBlacklistPrefs(blacklistPrefs))) {
blacklistPosts(blacklistPrefs);
}
});chrome.runtime.sendMessage({storage: ['useChat', 'campaigns']}, function(response) {
var useChat = response.storage.useChat;
var currentHref = document.location.href;
var currentCampaign, storedCampaigns, storedCampaignsArray;if (!campaigns || campaigns.length == 0) {
storedCampaigns = response.storage.campaigns;
storedCampaignsArray = JSON.parse(storedCampaigns);
currentCampaign = storedCampaignsArray.find(function(campaign) {
return currentHref.indexOf(campaign.url) >= 0;
});
}if ((useChat == "true") &&
username &&
((currentHref.indexOf(username + "/campaigns") >= 0) ||
currentCampaign)) {if (currentCampaign) {
pctChat.initializeChat(username, [ currentCampaign ], true);
} else {
var campaignsArray = campaignsToArray(campaigns);
saveCampaigns(campaignsArray);
pctChat.initializeChat(username, campaignsArray);
}
}
});chrome.runtime.sendMessage({storage: ['useHighlighter', 'highlightColor']}, function(response) {
var useHighlighter = response.storage.useHighlighter,
highlightColor = response.storage.highlightColor;if ((useHighlighter == "true") && (document.location.href.indexOf("/campaigns") >= 0)) {
highlightNew(highlightColor);
}
});})();
Oladon |
1 person marked this as a favorite. |
Something is interfering with your browser's storage mechanism (called localStorage). I've tried repeatedly, and the only time that error occurs is when your campaigns couldn't be saved to the browser settings for some reason.
Would each of you please try disabling all other extensions, restarting Chrome, visiting your base user's campaigns page, and then clicking on a campaign thread and letting me know if it works? Tim already tried this, but he may be having a different issue.
Additionally, are any of you using Incognito mode? (If so, that would likely cause it. Please try a regular Chrome window and let me know the results.)
Me'mori |
Found how to get the text, this is what I have listed.
extensions::uncaught_exception_handler:8 Error in event handler for (unknown): SyntaxError: Unexpected token u
at chrome-extension://ibfgfbafipmhmjohndaekilkkldeahgd/content/pct.js:265:31ha ndler @ extensions::uncaught_exception_handler:8exports.handle @ extensions::uncaught_exception_handler:100EventImpl.dispatch_ @ extensions::event_bindings:384EventImpl.dispatch @ extensions::event_bindings:401target.(anonymous function) @ extensions::SafeBuiltins:19$Array.forEach.publicClass.(anonymous function) @ extensions::utils:94dispatchOnMessage @ extensions::messaging:316
Papa-DRB |
Disabled all extensions, excepting yours.
Disabled open windows on startup and just had new tab.
PF12, campaigns tab.
Error in event handler for (unknown): SyntaxError: Unexpected token u
at chrome-extension://ibfgfbafipmhmjohndaekilkkldeahgd/content/pct.js:265:31ha ndler @ extensions::uncaught_exception_handler:8exports.handle @ extensions::uncaught_exception_handler:100EventImpl.dispatch_ @ extensions::event_bindings:384EventImpl.dispatch @ extensions::event_bindings:401propertyNames.forEach.target.(anonymous function) @ extensions::SafeBuiltins:19$Array.forEach.publicClass.(anonymous function) @ extensions::utils:94dispatchOnMessage @ extensions::messaging:316
No chat button anywhere on the screen that I can find.
Walter das Sombras |
No, I'm not in incognito mode.
Still nothing. I disabled all the extensions, to no result. I also disabled and reactivated the extension, and tried to reinstall it, to no avail.
Thinking about your comment about the campaigns not being saved, I've logged out of chrome to try it, and still nothing. I'm not sure where the campaigns are saved, but I don't think they are being saved at all.
In any paizo page there are three cookies:
- Store
woinst
wosid
Plus, the last modification date on the "external_extensions.json" file was on the 13th, way before I installed the app.
Does that say anything?
Oladon |
Thanks for the help debugging, everyone; I've figured it out. It's because you all have silly aliases... :)
It's because the extension looks at your campaigns URL to try to determine if you're on your own campaigns page, and you guys' URLs won't match your base alias.
Version 1.1.2 will be out as soon as I can get it tested and be sure it fixes the issue. I'll let you all know when that is.
Oladon |
NEW VERSION
Version 1.1.2 is out with a fix for the chat feature with users whose names contain spaces (or other characters that don't translate to your Paizo profile URL). If it didn't work for you before, give this version a try and let me know the results.
NOTE: The chat feature will not work if your base Paizo username contains " aka". Shouldn't be many people to whom that applies.