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

Update social media modules #54

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open

Update social media modules #54

wants to merge 9 commits into from

Conversation

akohlbre
Copy link
Contributor

  • Adds support for blocking to the events module (to allow for a module to wait on the result of a listener)
  • Updates socialMediaActivity to use the event model
  • Updates socialMediaLinkSharing to use the new interface to socialMediaActivity
  • Adds documentation in socialMediaActivity

Remaining tasks for these modules are in #17 and #23.

src/events.js Outdated Show resolved Hide resolved
* @param blocking - whether the listener should be blocking. Allows canceling the event.
* Filter generated events to only the listeners for the specific event type.
* @param {socialMediaActivityCallback} listener - The listener that may be notified.
* @param {Array} listenerArguments - The event about to be sent to the listener.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array of what?

Comment on lines 117 to 119
/**
* @type {events.event<socialMediaActivityCallback, socialMediaActivityOptions}
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See how events are annotated in other modules. We might eventually change the format, but it's the least-bad I could come up with for now.

Comment on lines 120 to 123
export const onSocialMediaActivity = events.createEvent({
addListenerCallback: addListener,
notifyListenersCallback: notifyFilter
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A big-picture design question for socialMediaActivity and socialMediaLinkSharing: do we want one event for all the platforms, or one event per platform? An advantage of the former is we avoid some repetition. An advantage of the latter is library users might otherwise shoot themselves in the feet by mixing and matching platforms and activity types.


/**
* Options when adding a social media activity event listener.
* @typedef {Object} socialMediaActivityOptions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been trying to establish a convention of lower camel case for callback types and upper camel case for other types (including @callback functions that aren't really callbacks).

/**
* Determine the audience of a Facebook post or reshare.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and throughout, when parsing platform-specific values, please make sure to document what the source data is and what assumptions you're making in parsing.

* This information is not included in the web request, nor is it attached to the generated post,
* so the only way to get it is by watching the user click the reshare button, which
* the content script does.
* @return {Promise} - The source of the last reshare ("person" or "page").
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What type of Promise?

/**
* For a given subreddit name, return whether it is private or public.
* @param {string} subredditName - The name of the subreddit, without leading "r/".
* @return {Promise} - resolves to a string representing the subreddit's status, or "unknown".
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What type of Promise?

@jonathanmayer jonathanmayer added documentation Improvements or additions to documentation enhancement New feature or request labels Apr 10, 2021
standardize return values
add support for facebook reshares with 'include original post' option
add support for old reddit
@akohlbre
Copy link
Contributor Author

This PR now contains all the code changes we're currently planning. I'll be pushing more documentation updates shortly, namely:

  • Longer explanatory comments about usage at the top of SMA and SMLS
  • Using the @namespace convention for documenting events and their associated object
  • Clearer documentation for which fields are relevant to which event types in SMA
  • More specific documentation about how we interact with platforms
  • More specific documentation for a few return types (e.g. anything currently just @returns {Object})

@@ -23,6 +23,10 @@ import { facebookLinkShimRegExp, parseFacebookLinkShim, removeFacebookLinkDecora
const trackedReshares = []
let mostRecentReshare = null;

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than having content scripts check a private window permission with extension storage (lines 13-16 above), we've migrated to sending the private window status and letting the background script filter events. See other modules for examples.

@@ -23,6 +23,10 @@ import { facebookLinkShimRegExp, parseFacebookLinkShim, removeFacebookLinkDecora
const trackedReshares = []
let mostRecentReshare = null;

/**
* Note the source of a reshare when the user clicks the button, in case it's wanted later.
* @param {Object} clicked - the page element that we were listening for clicks on.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a DOM Element? Could you give a more specific type?

Comment on lines 23 to 24
const trackedReshares = []
let mostRecentReshare = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation!

@@ -63,6 +70,7 @@ import { facebookLinkShimRegExp, parseFacebookLinkShim, removeFacebookLinkDecora
}
}

// periodically add listeners to newly-loaded posts.
setInterval(() => reshareSourceTracking(), 3000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could just give reshareSourceTracking as the callback. Would also specify the interval as a constant and pause the timer when the page doesn't have attention.

@@ -72,8 +80,8 @@ import { facebookLinkShimRegExp, parseFacebookLinkShim, removeFacebookLinkDecora
* @param response -- an object to add found links to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Types?

Comment on lines 127 to 138
if (facebook) {
socialMediaActivity.registerFacebookActivityTracker(facebookLinks, ["post", "reshare"]);
socialMediaActivity.onFacebookActivity.addListener(facebookLinks, {
eventTypes: ['post', 'reshare']});
}
if (reddit) {
socialMediaActivity.registerRedditActivityTracker(redditLinks, ["post"]);
socialMediaActivity.onRedditActivity.addListener(redditLinks, {
eventTypes: ['post']});
}
if (twitter) {
socialMediaActivity.registerTwitterActivityTracker(twitterLinks, ["tweet", "retweet", "favorite"]);
socialMediaActivity.onTwitterActivity.addListener(twitterLinks, {
eventTypes: ['tweet', 'retweet', 'favorite']});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like some logic is needed in here for adding multiple listeners.

Comment on lines +167 to +174
/**
* Given events that were set up to be "tracked"-type notifications but do not match the current
* listener's match patterns, turn them into one or more "untracked"-type notifications instead.
* @param {socialMediaShareDetails[]} trackedEvents - a set of non-matching share events.
* @returns {socialMediaShareDetails[]} - the tracked events stripped and condensed into untracked events.
* @private
*/
function trackedToUntracked(trackedEvents) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would just combine this with the prior function.

newEvents.push(newEvent);
}
}
return newEvents;
}

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to add logic for teardown after removing listeners.

* @private
*/
function isTwitterLink(url) {
const twitterLink = /twitter\.com\/[0-9|a-z|A-Z|_]*\/status\/([0-9]*)\//;
const twitterLink = /twitter\.com\/[0-9|a-z|A-Z|_]*\/status\/([0-9]*)/;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would parse to a URL, check the hostname, then check the path.

*/
const debugLog = debugging.getDebuggingLog("socialMediaLinkSharing");
export const onShare = events.createEvent({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the boundary between socialMediaActivity and socialMediaLinkSharing should be a bit different from what it is. Currently, socialMediaActivity exposes functions for looking up tweets, posts, and subreddits, and socialMediaLinkSharing has to call those functions. It would be preferable if we could keep those functions internal to socialMediaActivity and only expose them if study developers eventually need them. The information that socialMediaLinkSharing has to obtain itself is also information that many callers to socialMediaActivity would want anyway. A possible approach would be a listener option for socialMediaActivity that indicates shared tweets and posts should be resolved, plus adding subreddit status to reddit events.

* @property {number} eventTime - timestamp of user action.
* @property {string} tweetText - for a tweet, the content of the tweet.
* @property {string[]} tweetAttachments - for a tweet, any links attached to the tweet.
* @property {string} sharedId - for a favorite or share, the Twitter ID of the favorited or retweeted tweet.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not include a post ID for all Twitter, Facebook, and Reddit events?

@@ -28,17 +29,155 @@ permissions.check({
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The permissions.check call above should go in the add listener callback functions, with the right match pattern and permissions (webRequestBlocking?) for the event type and listener options.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants