Browse Source

Move back tweet author score under profile picture.

master
Kuzirashi 6 years ago
parent
commit
95c39b53a4
  1. 3
      .editorconfig
  2. 23
      src/content-scripts/twitter/js/ProfilePopup.js
  3. 5
      src/content-scripts/twitter/js/Settings.js
  4. 64
      src/content-scripts/twitter/js/TweetsAuthorScore.js
  5. 5
      src/content-scripts/twitter/js/index.js
  6. 520
      src/content-scripts/twitter/styles/twitter.scss

3
.editorconfig

@ -0,0 +1,3 @@
[*]
indent_style = space
indent_size = 2

23
src/content-scripts/twitter/js/ProfilePopup.js

@ -17,18 +17,31 @@ export class ProfilePopup {
const clusters = await this.api.getTwitterUserClusters(this.userTwitterId);
const displayPopup = () => {
let popupNode, closePopup;
const displayPopup = event => {
const POPUP_CLASS = 'HiveExtension-Twitter_popup-profile';
const POPUP_HIDDEN_CLASS = `${POPUP_CLASS}-hidden`;
const removePopupElement = () => {
displayElement.querySelector(`.${POPUP_CLASS}`).remove();
document.removeEventListener('click', closePopup);
};
event.stopPropagation();
if (displayElement.querySelector(`.${POPUP_CLASS}`)) {
if (popupNode && (event.target !== popupNode && !popupNode.contains(event.target))) {
removePopupElement();
}
return;
}
const roundedAllCryptoScore = Math.round(allCryptoScore);
const cryptoPercentage = Math.floor((roundedAllCryptoScore / CONFIG.MAX_SCORE) * 100);
const popupNode = document.createElement('div');
popupNode = document.createElement('div');
popupNode.classList.add(POPUP_CLASS);
popupNode.classList.add(POPUP_HIDDEN_CLASS);
@ -121,14 +134,14 @@ export class ProfilePopup {
popupNode.classList.remove(POPUP_HIDDEN_CLASS);
setTimeout(() => {
const closePopup = event => {
closePopup = event => {
if (event.target === popupNode || popupNode.contains(event.target)) {
return;
}
displayElement.querySelector(`.${POPUP_CLASS}`).remove();
event.stopPropagation();
document.removeEventListener('click', closePopup);
removePopupElement();
};
document.addEventListener('click', closePopup);

5
src/content-scripts/twitter/js/Settings.js

@ -0,0 +1,5 @@
export class ExtensionSettings {
get isDarkTheme() {
return Boolean(document.querySelector('.js-nightmode-icon.Icon--crescentFilled'));
}
}

64
src/content-scripts/twitter/js/TweetsAuthorScore.js

@ -1,22 +1,25 @@
import { ProfilePopup } from './ProfilePopup';
const TWEET_AUTHOR_SCORE_EXTENSION_CLASS_NAME = 'HiveExtension-Twitter_tweet-author-score';
const TWEET_AUTHOR_SCORE_CLASS = 'HiveExtension-Twitter_tweet-author-score';
const TWEET_INDIVIDUAL_SCORE_CLASS = 'HiveExtension-Twitter_tweet-individual-score';
const TWEETS_SELECTOR = '.tweet';
export class TwitterTweetsAuthorScoreExtension {
api;
settings;
constructor(_api) {
this.api = _api;
constructor(api, settings) {
this.api = api;
this.settings = settings;
}
async start() {
this.addScoreToTweetFooter();
this.addScoreBelowProfilePicture();
}
async addScoreToTweetFooter() {
document.querySelectorAll(TWEETS_SELECTOR).forEach(async tweet => {
const processedClassName = `${TWEET_AUTHOR_SCORE_EXTENSION_CLASS_NAME}-processed`;
const processedClassName = `${TWEET_INDIVIDUAL_SCORE_CLASS}-processed`;
if (tweet.classList.contains(processedClassName)) {
return;
@ -29,22 +32,20 @@ export class TwitterTweetsAuthorScoreExtension {
const { name: clusterName, score: userScore } = await this.api.getTwitterUserScore(authorId);
const userScoreDisplay = document.createElement('div');
userScoreDisplay.classList.add(TWEET_AUTHOR_SCORE_EXTENSION_CLASS_NAME);
userScoreDisplay.classList.add(TWEET_INDIVIDUAL_SCORE_CLASS);
userScoreDisplay.classList.add('ProfileTweet-action');
userScoreDisplay.innerHTML = `<button class="${TWEET_AUTHOR_SCORE_EXTENSION_CLASS_NAME}_display ProfileTweet-actionButton js-tooltip" data-original-title="${clusterName} Score">
userScoreDisplay.innerHTML = `<button class="${TWEET_INDIVIDUAL_SCORE_CLASS}_display ProfileTweet-actionButton js-tooltip" data-original-title="${clusterName} Score">
<div class="IconContainer">
<span class="Icon Icon--medium">
<svg viewBox="0 0 36 36" class="${TWEET_AUTHOR_SCORE_EXTENSION_CLASS_NAME}_display_icon">
<svg viewBox="0 0 36 36" class="${TWEET_INDIVIDUAL_SCORE_CLASS}_display_icon">
<use xlink:href="#hive-icon" />
</svg>
</span>
</div>
<span class="ProfileTweet-actionCount">
<span class="${TWEET_AUTHOR_SCORE_EXTENSION_CLASS_NAME}_display_score">${Math.round(
userScore
)}</span>
<span class="${TWEET_INDIVIDUAL_SCORE_CLASS}_display_score">${Math.round(userScore)}</span>
</span>
</button>
@ -60,4 +61,45 @@ export class TwitterTweetsAuthorScoreExtension {
}
});
}
async addScoreBelowProfilePicture() {
document.querySelectorAll(TWEETS_SELECTOR).forEach(async tweet => {
const processedClassName = `${TWEET_AUTHOR_SCORE_CLASS}-processed`;
if (tweet.classList.contains(processedClassName)) {
return;
}
tweet.classList.add(processedClassName);
const authorId = tweet.getAttribute('data-user-id');
const { score: userScore } = await this.api.getTwitterUserScore(authorId);
const tweetIsThread =
Boolean(tweet.querySelector('.self-thread-tweet-cta')) ||
tweet.parentElement.parentElement.classList.contains('ThreadedConversation-tweet');
let threadClass = TWEET_AUTHOR_SCORE_CLASS + '_display-in-thread';
if (this.settings.isDarkTheme) {
threadClass += '-dark';
}
const userScoreDisplay = document.createElement('div');
userScoreDisplay.classList.add(TWEET_AUTHOR_SCORE_CLASS);
userScoreDisplay.innerHTML = `<b class="${TWEET_AUTHOR_SCORE_CLASS}_display ${
tweetIsThread ? threadClass : ''
}">${Math.round(userScore)}</b>`;
const popup = new ProfilePopup(authorId, this.api);
popup.showOnClick(userScoreDisplay);
const accountGroup = tweet.querySelector('.stream-item-header');
if (accountGroup) {
accountGroup.appendChild(userScoreDisplay);
}
});
}
}

5
src/content-scripts/twitter/js/index.js

@ -5,6 +5,7 @@ import { TwitterProfileScoreExtension } from './TwitterProfileScore';
import { TwitterTweetsAuthorScoreExtension } from './TweetsAuthorScore';
import { CONFIG } from '../../../config';
import { ExtensionIcons } from './Icons';
import { ExtensionSettings } from './Settings';
const observeDOM = (() => {
const MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
@ -37,8 +38,10 @@ function getOptionValue(name) {
const cache = new CustomCache();
const api = new HiveAPI(CONFIG.API_HOST, clusterToDisplay, cache);
const settings = new ExtensionSettings();
const twitterProfileScore = new TwitterProfileScoreExtension(api);
const twitterTweetsAuthorScoreExtension = new TwitterTweetsAuthorScoreExtension(api);
const twitterTweetsAuthorScoreExtension = new TwitterTweetsAuthorScoreExtension(api, settings);
const icons = new ExtensionIcons();
async function runExtensions() {

520
src/content-scripts/twitter/styles/twitter.scss

@ -1,254 +1,296 @@
.HiveExtension-Twitter {
&_profile-score {
cursor: pointer;
}
&_tweet-author-score {
position: relative;
&_display {
$root: &;
color: #657786;
$highlightColor: #817aff;
&_score {
display: inline-block;
font-size: 12px;
font-weight: bold;
line-height: 1;
margin-left: 6px;
position: relative;
vertical-align: text-bottom;
}
&_icon {
fill: #657786;
overflow: visible;
width: 18px;
height: 18px;
margin-top: 2px;
}
&:hover {
#{$root}_score {
color: $highlightColor;
}
#{$root}_icon {
fill: $highlightColor;;
}
}
}
&_profile-score {
cursor: pointer;
}
&_tweet-author-score {
color: #4ab3f4;
text-align: center;
display: block;
float: left;
margin-top: 55px;
margin-left: -58px;
position: absolute;
width: 48px;
&_display {
z-index: 3;
display: block;
position: relative;
user-select: none;
&-in-thread {
background: white;
.js-navigation-active.stream-item &,
.tweet:hover & {
background: #f5f8fa;
}
&-dark {
background: #15202b;
.js-navigation-active.stream-item &,
.tweet:hover & {
background: #15202b;
}
}
}
}
}
&_tweet-individual-score {
position: relative;
&_display {
$root: &;
color: #657786;
$highlightColor: #817aff;
&_score {
display: inline-block;
font-size: 12px;
font-weight: bold;
line-height: 1;
margin-left: 6px;
position: relative;
vertical-align: text-bottom;
}
&_icon {
fill: #657786;
overflow: visible;
width: 18px;
height: 18px;
margin-top: 2px;
}
&:hover {
#{$root}_score {
color: $highlightColor;
}
#{$root}_icon {
fill: $highlightColor;
}
}
}
}
&_popup {
&-profile {
position: absolute;
background: #fafbfd;
padding: 10px;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.25);
width: 300px;
z-index: 1000;
font-size: 14px;
line-height: 19.25px;
user-select: none;
color: #14171a;
&_title {
color: #545454;
margin: 0;
display: block;
font-size: 1.17em;
font-weight: bold;
}
&_content {
border: 1px solid #eeedff;
padding: 1rem;
background-color: white;
border-radius: 6px;
}
&_followers {
display: flex;
justify-content: space-between;
margin-top: 24px;
text-align: center;
overflow: scroll;
margin-top: 10px;
&_follower {
font-weight: 600;
background-color: white;
padding: 12px 16px;
margin-right: 8px;
border-radius: 6px;
border: 1px solid #eeedff;
&_image {
height: 40px;
width: 40px;
overflow: hidden;
border-radius: 50%;
}
&_name {
width: 60px;
margin-top: 8px;
font-size: 10px;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
&-hidden {
visibility: hidden;
}
&_cluster-score {
position: relative;
&:nth-of-type(n + 3) {
margin-top: 10px;
}
&_right {
position: absolute;
right: 0;
top: 0;
&_bold {
font-weight: 500;
font-size: 12px;
}
&_small {
color: #9ca4ab;
font-size: 10px;
}
}
&_progress-bar {
width: 100%;
position: relative;
margin-top: 8px;
&_popup {
&-profile {
&_bg {
height: 4px;
border-radius: 2px;
background-color: #eeedff;
}
&_progress {
background-color: rgba(87, 77, 255, 0.7);
position: absolute;
background: #fafbfd;
padding: 10px;
box-shadow: 0 1px 3px 0 rgba(0,0,0,0.25);
width: 300px;
z-index: 1000;
font-size: 14px;
line-height: 19.25px;
&_title {
color: #545454;
margin: 0;
display: block;
font-size: 1.17em;
font-weight: bold;
}
&_content {
border: 1px solid #eeedff;
padding: 1rem;
background-color: white;
border-radius: 6px;
}
&_followers {
display: flex;
justify-content: space-between;
margin-top: 24px;
text-align: center;
overflow: scroll;
margin-top: 10px;
&_follower {
font-weight: 600;
background-color: white;
padding: 12px 16px;
margin-right: 8px;
border-radius: 6px;
border: 1px solid #eeedff;
&_image {
height: 40px;
width: 40px;
overflow: hidden;
border-radius: 50%;
}
&_name {
width: 60px;
margin-top: 8px;
font-size: 10px;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
&-hidden {
visibility: hidden;
}
&_cluster-score {
position: relative;
&:nth-of-type(n + 3) {
margin-top: 10px;
}
&_right {
position: absolute;
right: 0;
top: 0;
&_bold {
font-weight: 500;
font-size: 12px;
}
&_small {
color: #9ca4ab;
font-size: 10px;
}
}
&_progress-bar {
width: 100%;
position: relative;
margin-top: 8px;
&_bg {
height: 4px;
border-radius: 2px;
background-color: #eeedff;
}
&_progress {
background-color:rgba(87, 77, 255, 0.70);
position: absolute;
height: 4px;
border-radius: 4px;
top: -1px;
left: -1px;
right: 0;
border: 1px solid white;
}
}
}
}
height: 4px;
border-radius: 4px;
top: -1px;
left: -1px;
right: 0;
border: 1px solid white;
}
}
}
}
}
}
.radial-progress {
$circle-size: 160px;
$circle-background: #d6dadc;
$circle-color: #8784ff;
$inset-size: $circle-size - 20px;
$inset-color: #fbfbfb;
$transition-length: 1s;
$percentage-font-size: 22px;
$percentage-text-width: 57px;
margin: 30px auto;
width: $circle-size;
height: $circle-size;
background-color: $circle-background;
border-radius: 50%;
$circle-size: 160px;
$circle-background: #d6dadc;
$circle-color: #8784ff;
$inset-size: $circle-size - 20px;
$inset-color: #fbfbfb;
$transition-length: 1s;
$percentage-font-size: 22px;
$percentage-text-width: 57px;
margin: 30px auto;
width: $circle-size;
height: $circle-size;
background-color: $circle-background;
border-radius: 50%;
.circle {
.mask,
.fill,
.shadow {
width: $circle-size;
height: $circle-size;
position: absolute;
border-radius: 50%;
}
.mask,
.fill {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
border-radius: 50%;
}
.mask {
clip: rect(0px, $circle-size, $circle-size, $circle-size/2);
.fill {
clip: rect(0px, $circle-size/2, $circle-size, 0px);
background-color: $circle-color;
}
}
}
.circle {
.mask, .fill, .shadow {
width: $circle-size;
height: $circle-size;
position: absolute;
border-radius: 50%;
}
.mask, .fill {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
border-radius: 50%;
$i: 0;
$increment: 180deg / 100;
@for $i from 1 through 100 {
&[data-progress="#{$i}"] {
.circle {
.mask.full,
.fill {
transform: rotate($increment * $i);
}
.fill.fix {
transform: rotate($increment * $i * 2);
}
}
}
}
.circle_inset {
width: $inset-size;
height: $inset-size;
position: absolute;
margin-left: ($circle-size - $inset-size)/2;
margin-top: ($circle-size - $inset-size)/2;
.mask {
clip: rect(0px, $circle-size, $circle-size, $circle-size/2);
.fill {
clip: rect(0px, $circle-size/2, $circle-size, 0px);
background-color: $circle-color;
}
}
}
$i: 0;
$increment: 180deg / 100;
@for $i from 1 through 100 {
&[data-progress="#{$i}"] {
.circle {
.mask.full, .fill {
transform: rotate($increment * $i);
}
.fill.fix {
transform: rotate($increment * $i * 2);
}
}
}
}
.circle_inset {
width: $inset-size;
height: $inset-size;
position: absolute;
margin-left: ($circle-size - $inset-size)/2;
margin-top: ($circle-size - $inset-size)/2;
background-color: $inset-color;
border-radius: 50%;
.percentage {
.numbers {
$width: 90px;
$height: 68px;
text-align: center;
margin-left: ($inset-size - $width) / 2;
width: $width;
height: $height;
margin-top: ($inset-size - $height) / 2;
&_main {
width: $percentage-text-width;
display: inline-block;
vertical-align: top;
text-align: center;
font-weight: 800;
font-size: $percentage-font-size;
font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
color: black;
}
}
}
background-color: $inset-color;
border-radius: 50%;
.percentage {
.numbers {
$width: 90px;
$height: 68px;
text-align: center;
margin-left: ($inset-size - $width) / 2;
width: $width;
height: $height;
margin-top: ($inset-size - $height) / 2;
&_main {
width: $percentage-text-width;
display: inline-block;
vertical-align: top;
text-align: center;
font-weight: 800;
font-size: $percentage-font-size;
font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
color: black;
}
}
}
}
}
.ProfileTweet-action--dm {
min-width: 60px;
}
min-width: 60px;
}

Loading…
Cancel
Save