Skip to content

Commit

Permalink
add rules: allow category, allow navigation, show article preview
Browse files Browse the repository at this point in the history
  • Loading branch information
azaky committed Oct 27, 2020
1 parent 8e5d813 commit 21f170a
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 6 deletions.
45 changes: 41 additions & 4 deletions extension/src/content_script/InGamePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import * as util from './util';
import { useData } from './DataContext';

export function InGamePanel() {
const data = useData();
const { currentState, currentRound, rules, username, roomId } = data;
const { currentState, currentRound, rules } = useData();

// enforce rules
useEffect(() => {
Expand Down Expand Up @@ -37,6 +36,29 @@ export function InGamePanel() {
window.addEventListener('keydown', handleCtrlf);
}

// hide popups
let popupObserver;
if (
typeof rules.showArticlePreview === 'boolean' &&
!rules.showArticlePreview
) {
popupObserver = new MutationObserver((mutationsList) => {
mutationsList.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (
node.tagName === 'DIV' &&
node.classList.contains('mwe-popups')
) {
node.remove();
}
});
}
});
});
popupObserver.observe(document.body, { childList: true });
}

return () => {
// restore hidden elements
hiddenElements.forEach((id) => {
Expand All @@ -49,14 +71,18 @@ export function InGamePanel() {
if (handleCtrlf) {
window.removeEventListener('keydown', handleCtrlf);
}

if (popupObserver) {
popupObserver.disconnect();
}
};
}, [currentState.finished]);

// override a.click
useEffect(() => {
if (currentState.finished) return;

const createClickHandler = (link) => {
const createClickHandler = (link, nav) => {
return (e) => {
if (!link) return;

Expand Down Expand Up @@ -85,6 +111,13 @@ export function InGamePanel() {
return;
}

// navigation pages
if (nav && !rules.allowNav && typeof rules.allowNav === 'boolean') {
toast.error(`You are not allowed to click navigational links!`);
console.log('Ignoring navigational link:', link);
return;
}

console.log('Navigating to:', article);

chrome.storage.local.get(['localState'], ({ localState }) => {
Expand All @@ -101,8 +134,12 @@ export function InGamePanel() {
};
};

const isNav = (el) => !!el.closest('.navbox');

const links = [...document.getElementsByTagName('A')];
const clickHandlers = links.map((link) => createClickHandler(link.href));
const clickHandlers = links.map((link) =>
createClickHandler(link.href, isNav(link))
);
links.forEach((link, i) =>
link.addEventListener('click', clickHandlers[i])
);
Expand Down
73 changes: 71 additions & 2 deletions extension/src/content_script/components/Rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +244,26 @@ export function Rules(props) {
onRulesChange({ allowDisambiguation: !!allow });
};

const onAllowBack = (allow) => {
const onAllowBackChange = (allow) => {
if (disabled || roundStarted) return;
onRulesChange({ allowBack: !!allow });
};

const onAllowCategoryChange = (allow) => {
if (disabled || roundStarted) return;
onRulesChange({ allowCategory: !!allow });
};

const onAllowNavChange = (allow) => {
if (disabled || roundStarted) return;
onRulesChange({ allowNav: !!allow });
};

const onShowArticlePreviewChange = (show) => {
if (disabled || roundStarted) return;
onRulesChange({ showArticlePreview: !!show });
};

const onBannedArticlesChange = (bannedArticles, callback) => {
if (disabled || roundStarted) {
if (callback) return callback();
Expand Down Expand Up @@ -279,6 +294,40 @@ export function Rules(props) {
);
};

const onShowNavInfo = () => {
toast.dismiss('help');
toast(
<div>
<h3>Navigation Links</h3>
Navigational links are the links contained in the tables on the bottom
of an article (if there's any). Usually they allow you to quickly
navigate between topics within the same area.
</div>,
{
closeOnClick: false,
autoClose: false,
toastId: 'help',
}
);
};

const onShowPreviewInfo = () => {
toast.dismiss('help');
toast(
<div>
<h3>Article Preview</h3>
Article Preview is the popup that shows when you hover a link. It
usually contains the summary of the article the link points to. When you
disable it, no popups will be shown when you hover any links.
</div>,
{
closeOnClick: false,
autoClose: false,
toastId: 'help',
}
);
};

return (
<nav class="vector-menu vector-menu-portal portal">
<h3 style={{ fontSize: '0.9em' }}>
Expand Down Expand Up @@ -309,7 +358,7 @@ export function Rules(props) {
<CheckBox
label="Allow back"
checked={rules.allowBack}
onChange={onAllowBack}
onChange={onAllowBackChange}
disabled={disabled}
onShowInfo={onShowBackInfo}
/>
Expand All @@ -319,6 +368,26 @@ export function Rules(props) {
onChange={onAllowDisambiguationChange}
disabled={disabled}
/>
<CheckBox
label="Allow category page"
checked={rules.allowCategory}
onChange={onAllowCategoryChange}
disabled={disabled}
/>
<CheckBox
label="Allow navigation links"
checked={rules.allowNav}
onChange={onAllowNavChange}
disabled={disabled}
onShowInfo={onShowNavInfo}
/>
<CheckBox
label="Show article preview"
checked={rules.showArticlePreview}
onChange={onShowArticlePreviewChange}
disabled={disabled}
onShowInfo={onShowPreviewInfo}
/>
</div>
<BannedArticles
bannedArticles={rules.bannedArticles}
Expand Down
37 changes: 37 additions & 0 deletions server/game.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ const createRoom = (host, id, _lang, _mode) => {
allowCtrlf: true,
allowDisambiguation: true,
allowBack: true,
allowNav: true,
allowCategory: true,
showArticlePreview: true,
bannedArticles: [],
},
leaderboard: [
Expand Down Expand Up @@ -149,6 +152,7 @@ const validateArticle = async (title, lang) => {
title: body.titles.canonical,
normalizedTitle: body.titles.normalized,
thumbnail: (body.thumbnail && body.thumbnail.source) || '',
namespace: (body.namespace && body.namespace.id) || 0,
};
} catch (e) {
console.error(`Error validating article [lang=${lang}][${title}]:`, e);
Expand Down Expand Up @@ -334,6 +338,13 @@ const socketHandler = async (socket) => {
});
return;
}
if (validated.namespace !== 0) {
ack({
success: false,
message: 'Start article cannot be a special Wikipedia page',
});
return;
}
data.currentRound.start = validated.title;
data.currentRound.startThumbnail = validated.thumbnail;
} else {
Expand All @@ -354,6 +365,13 @@ const socketHandler = async (socket) => {
});
return;
}
if (validated.namespace !== 0) {
ack({
success: false,
message: 'Target article cannot be a special Wikipedia page',
});
return;
}
data.currentRound.target = validated.title;
data.currentRound.targetThumbnail = validated.thumbnail;
} else {
Expand Down Expand Up @@ -648,6 +666,25 @@ const socketHandler = async (socket) => {
return;
}

if (
!room.rules.allowCategory &&
(validated.namespace === 14 || validated.namespace === 15) // https://en.wikipedia.org/wiki/Wikipedia%3ANamespace
) {
ack({
success: false,
message: `${article} is a category page! You can't go there!`,
});
return;
}

if (validated.namespace !== 0 && validated.namespace !== 14) {
ack({
success: false,
message: `${article} is a special Wikipedia page! You can't go there!`,
});
return;
}

// Double articles checks
// Since clicking improvement in client side, perhaps we don't need really this.
// However, there's no harm in more precaution (other than the slight advantage to users)
Expand Down

0 comments on commit 21f170a

Please sign in to comment.