{renderDotLinks(pinnedPostsCount)}
diff --git a/src/app/components/cards/PostsList.scss b/src/app/components/cards/PostsList.scss
index 1156439c4a..029c6017c9 100644
--- a/src/app/components/cards/PostsList.scss
+++ b/src/app/components/cards/PostsList.scss
@@ -41,190 +41,199 @@
}
}
}
+
+:root {
+ --pinned: '0';
+}
.prev, .next, .carouselDots, .collapseShowPinned {
- display: none;
+ display: block;
}
-@include MQ(M) {
+.pinnedPostsContainer {
+ position: relative;
+ margin: auto;
+ margin-bottom: 1em;
+ overflow-x: clip;
+ overflow-y: visible;
+ z-index: 1;
- :root {
- --pinned: '0';
- }
-
- .prev, .next, .carouselDots, .collapseShowPinned {
- display: block;
- }
-
- .pinnedPostsContainer {
- position: relative;
- margin: auto;
- margin-bottom: 1em;
- overflow-x: clip;
- overflow-y: visible;
- z-index: 1;
-
- .pinnedPosts {
- display: flex;
- margin: 0;
- padding: 0;
- transition: transform 0.5s ease;
+ .pinnedPosts {
+ display: flex;
+ margin: 0;
+ padding: 0;
+ transition: transform 0.5s ease;
+ transform: translateX(calc(var(--pinned)*2));
+ @include MQ(M) {
transform: translateX(var(--pinned));
}
- .isPinned {
- box-sizing: border-box;
+ }
+ .isPinned {
+ box-sizing: border-box;
+ flex: 0 0 calc(100% - 1rem);
+ @include MQ(M) {
flex: 0 0 calc(50% - 1rem);
- margin: 0 0.5rem;
}
- .prev, .next {
+ margin: 0 0.5rem;
+ }
+ .prev, .next {
+ cursor: pointer;
+ position: absolute;
+ top: 50%;
+ width: auto;
+ padding: 16px;
+ margin-top: -31px;
+ font-weight: bold;
+ transition: 0.2s ease;
+ border-radius: 0 3px 3px 0;
+ user-select: none;
+ z-index: 100;
+ opacity: 30%;
+ @include font-size(18px);
+ @include themify($themes) {
+ background-color: themed('buttonBackground');
+ color: themed('buttonText');
+ }
+ }
+
+ .next {
+ right: 0;
+ margin-right: 0 !important;
+ border-radius: 3px 0 0 3px;
+ }
+
+ .prev:hover, .next:hover {
+ @include themify($themes) {
+ background-color: themed('buttonBackgroundHover');
+ color: themed('buttonTextHover');
+ opacity: 80%;
+ }
+ }
+
+ .carouselDots {
+ margin: 0.2rem 0 0 0.5rem;
+
+ .dot {
cursor: pointer;
- position: absolute;
- top: 50%;
- width: auto;
- padding: 16px;
- margin-top: -31px;
- font-weight: bold;
+ display: inline-block;
+ border-radius: 50%;
+ padding: 0.3rem;
+ margin: 0.5rem;
+ opacity: 80%;
transition: 0.2s ease;
- border-radius: 0 3px 3px 0;
- user-select: none;
- z-index: 100;
- opacity: 30%;
- @include font-size(18px);
@include themify($themes) {
- background-color: themed('buttonBackground');
- color: themed('buttonText');
+ background-color: themed('textColorPrimary');
}
}
-
- .next {
- right: 0;
- margin-right: 0 !important;
- border-radius: 3px 0 0 3px;
- }
-
- .prev:hover, .next:hover {
+
+ .dot:hover {
+ opacity: 80%;
@include themify($themes) {
- background-color: themed('buttonBackgroundHover');
- color: themed('buttonTextHover');
- opacity: 80%;
+ background-color: themed('colorAccent');
}
}
- .carouselDots {
- margin: 0.2rem 0 0 0.5rem;
- float: left;
-
- .dot {
- cursor: pointer;
- display: inline-block;
- border-radius: 50%;
- padding: 0.3rem;
- margin: 0.5rem;
- opacity: 80%;
- transition: 0.2s ease;
- @include themify($themes) {
- background-color: themed('textColorPrimary');
- }
- }
-
- .dot:hover {
- opacity: 80%;
- @include themify($themes) {
- background-color: themed('colorAccent');
- }
+ .dot.active {
+ @include themify($themes) {
+ background-color: themed('colorAccent');
}
-
- .dot.active {
- @include themify($themes) {
- background-color: themed('colorAccent');
- }
+ border-radius: 50%;
+ padding: 0.3rem;
+ @include MQ(M) {
border-radius: 25%;
padding: 0.3rem 1.3rem;
}
}
-
- .articles {
+ }
+
+ .articles {
- &__summary {
- height: 100%;
+ &__summary {
+ height: 100%;
+ }
+
+ &__summary-header {
+ padding: 0.5rem 0 !important;
+ a.timestamp__link::before {
+ content: "\a";
+ white-space: pre;
}
-
- &__summary-header {
- padding: 0.5rem 0 !important;
- a.timestamp__link::before {
- content: "\a";
- white-space: pre;
+ }
+
+ &__content {
+ display: block !important;
+ }
+ &__content-block {
+ display: block !important;
+ width: 100% !important;
+ flex: none;
+ &--img {
+ margin-bottom: 0.5rem !important;
+ height: 250px;
+ overflow: hidden;
+ @include MQ(M) {
+ height: auto;
}
}
-
- &__content {
- display: block !important;
- }
- &__content-block {
- display: block !important;
- width: 100% !important;
+ &--text {
flex: none;
- &--img {
- height: auto;
- margin-bottom: 0.5rem !important;
- }
- &--text {
- flex: none;
- min-width: 100px !important;
-
- .PostSummary__body {
- white-space: wrap;
- padding-bottom: 0.5rem;
- }
+ min-width: 100px !important;
+
+ .PostSummary__body {
+ white-space: wrap;
+ padding-bottom: 0.5rem;
}
}
- &__h2 {
- margin-bottom: 0.5rem;
- }
+ }
+ &__h2 {
+ margin-bottom: 0.5rem;
+ }
- &__feature-img-container {
- display: flex !important;
+ &__feature-img-container {
+ display: flex !important;
+ @include MQ(M) {
width: 100% !important;
height: 250px !important;
}
+ }
- &__footer {
- padding-bottom: 20px;
- }
+ &__footer {
+ padding-bottom: 20px;
+ }
- &__summary-footer {
- position: absolute;
- display: block;
- bottom: 0;
-
- .Voting {
- float: none;
- }
- .VotesAndComments {
- .VotesAndComments__votes {
- padding-right: 0;
- }
+ &__summary-footer {
+ position: absolute;
+ display: block;
+ bottom: 0;
+
+ .Voting {
+ float: none;
+ }
+ .VotesAndComments {
+ .VotesAndComments__votes {
+ padding-right: 0;
}
- .PostSummary__time_author_category {
- padding-left: 0;
+ }
+ .PostSummary__time_author_category {
+ padding-left: 0;
- .Reblog__button {
- margin: 0;
- padding-right: 0;
- }
+ .Reblog__button {
+ margin: 0;
+ padding-right: 0;
}
}
}
}
-
- .collapseShowPinned {
- text-align: right;
- margin: 0.1rem 0.5rem 1rem 1rem;
-
- a {
- white-space: nowrap;
- padding: 0.5rem 0 0.5rem 0.5rem;
- }
+}
+
+.collapseShowPinned {
+ text-align: right;
+ margin: 0.1rem 0.5rem 1rem 1rem;
+ display: block;
+
+ a {
+ white-space: nowrap;
+ padding: 0.5rem 0 0.5rem 0.5rem;
}
}
diff --git a/src/app/components/cards/PrimaryNavigation.scss b/src/app/components/cards/PrimaryNavigation.scss
index 3d89d81ef7..e6b4d68229 100644
--- a/src/app/components/cards/PrimaryNavigation.scss
+++ b/src/app/components/cards/PrimaryNavigation.scss
@@ -8,7 +8,6 @@
padding: 0;
display: flex;
z-index: 100000;
- height: 60px;
@include themify($themes) {
@include MQ(M) {
diff --git a/src/app/components/elements/Tag.jsx b/src/app/components/elements/Tag.jsx
index 430683f56e..5434ca55ba 100644
--- a/src/app/components/elements/Tag.jsx
+++ b/src/app/components/elements/Tag.jsx
@@ -5,7 +5,7 @@ const Tag = ({ post }) => {
const tag = post.get('category');
const name = post.get('community_title', '#' + tag);
return (
-
@@ -126,9 +138,21 @@ export default class TagsIndex extends React.Component {
}
}
+const mapStateToProps = state => {
+ return {
+ tagsAll: state.global.get('tagsList', Map()),
+ };
+};
+
+const mapDispatchToProps = dispatch => ({
+ fetchTags: () => dispatch(fetchDataSagaActions.getTags()), // Dispatch the fetchTags action
+});
+
+const ConnectedTagsIndex = connect(mapStateToProps, mapDispatchToProps)(
+ TagsIndex
+);
+
module.exports = {
path: 'tags(/:order)',
- component: connect(state => ({
- tagsAll: state.global.get('tags', Map()),
- }))(TagsIndex),
+ component: ConnectedTagsIndex,
};
diff --git a/src/app/redux/FetchDataSaga.js b/src/app/redux/FetchDataSaga.js
index 687cff409f..ff16620380 100644
--- a/src/app/redux/FetchDataSaga.js
+++ b/src/app/redux/FetchDataSaga.js
@@ -23,6 +23,7 @@ const GET_COMMUNITY = 'fetchDataSaga/GET_COMMUNITY';
const LIST_COMMUNITIES = 'fetchDataSaga/LIST_COMMUNITIES';
const GET_SUBSCRIPTIONS = 'fetchDataSaga/GET_SUBSCRIPTIONS';
const GET_NOTICES = 'fetchDataSaga/GET_NOTICES';
+const GET_TAGSLIST = 'global/GET_TAGSLIST';
const GET_FOLLOWERS = 'fetchDataSaga/GET_FOLLOWERS';
const UPDATE_FOLLPWERSLIST = 'fetchDataSaga/UPDATE_FOLLPWERSLIST';
const GET_ACCOUNT_NOTIFICATIONS = 'fetchDataSaga/GET_ACCOUNT_NOTIFICATIONS';
@@ -40,6 +41,7 @@ export const fetchDataWatches = [
takeEvery(GET_COMMUNITY, getCommunity),
takeLatest(GET_SUBSCRIPTIONS, getSubscriptions),
takeLatest(GET_NOTICES, getNotices),
+ takeLatest(GET_TAGSLIST, getTags),
takeLatest(GET_FOLLOWERS, getFollowers),
takeLatest(UPDATE_FOLLPWERSLIST, updateFollowersList),
takeEvery(LIST_COMMUNITIES, listCommunities),
@@ -265,6 +267,21 @@ export function* getNotices(action) {
* Request Notices
* @param {string} name of account
*/
+
+export function* getTags() {
+ try {
+ const list = yield call(
+ callBridge,
+ 'get_trending_tags',
+ [null, 250],
+ 'condenser_api.'
+ );
+ yield put(globalActions.receiveTagsList(list));
+ } catch (error) {
+ console.log('Error Fetching receiveTagsList: ', error);
+ }
+}
+
export function* getFollowers(action) {
console.log(action.payload);
const { title, accountname, currentPage, per_page } = action.payload;
@@ -277,7 +294,6 @@ export function* getFollowers(action) {
[accountname, currentPage, per_page, 'blog'],
'condenser_api.'
);
- console.log(list);
yield put(globalActions.receiveFollowersList(list));
} catch (error) {
console.log('Error Fetching receiveFollowersList: ', error);
@@ -553,6 +569,11 @@ export const actions = {
payload,
}),
+ getTags: payload => ({
+ type: GET_TAGSLIST,
+ payload,
+ }),
+
getFollowers: payload => ({
type: GET_FOLLOWERS,
payload,
diff --git a/src/app/redux/GlobalReducer.js b/src/app/redux/GlobalReducer.js
index 64c15ed5c0..ded9314f10 100644
--- a/src/app/redux/GlobalReducer.js
+++ b/src/app/redux/GlobalReducer.js
@@ -36,6 +36,7 @@ export const GET_DGP = 'global/GET_DGP';
export const SET_DGP = 'global/SET_DGP';
const SET_VESTS_PER_STEEM = 'global/SET_VESTS_PER_STEEM';
const NOTICES = 'global/NOTICES';
+const TAGSLIST = 'global/TAGSLIST';
const FOLLOWERSLIST = 'global/FOLLOWERSLIST';
const postKey = (author, permlink) => {
@@ -161,6 +162,10 @@ export default function reducer(state = defaultState, action = {}) {
case NOTICES: {
return state.set('notices', fromJS(payload));
}
+ case TAGSLIST: {
+ console.log('SETTING STATE OF TAGSLIST', payload);
+ return state.set('tagsList', fromJS(payload));
+ }
case FOLLOWERSLIST: {
return state.set('followersList', fromJS(payload));
}
@@ -399,6 +404,11 @@ export const receiveNotices = payload => ({
payload,
});
+export const receiveTagsList = payload => ({
+ type: TAGSLIST,
+ payload,
+});
+
export const receiveFollowersList = payload => ({
type: FOLLOWERSLIST,
payload,
diff --git a/src/app/utils/CanonicalLinker.js b/src/app/utils/CanonicalLinker.js
index bebbd65ae3..d6265a98da 100644
--- a/src/app/utils/CanonicalLinker.js
+++ b/src/app/utils/CanonicalLinker.js
@@ -21,9 +21,36 @@ function read_md_canonical(metadata) {
function build_scheme(scheme, post) {
// https://github.com/bonustrack/steemscript/blob/master/apps.json
+ let tempCategory = post.category || '';
+
+ const tags = post.json_metadata.tags || [];
+
+ // Leave Options 1 and 2 uncommented for a combination of both approaches
+ // Option 1: Replace hive-xxxxxx in the URL with the community name. This doesn't impact non-community posts
+ const communityTitle = post.community_title || `#${tempCategory}` || '';
+ const sanitizedTitle = communityTitle.replace(/[^a-zA-Z0-9 ]/g, '').trim();
+ const urlFriendlyTitle = sanitizedTitle.replace(/\s+/g, '-').toLowerCase();
+ if (urlFriendlyTitle) {
+ tempCategory = urlFriendlyTitle;
+ }
+
+ // Option 2: Replace hive-xxxxxx in the URL with the first tag of a post
+ if (tempCategory.startsWith('hive-') && tags.length > 0) {
+ const firstTag = tags[0].startsWith('#')
+ ? tags[0].substring(1)
+ : tags[0];
+ tempCategory =
+ firstTag.startsWith('hive-') && tags.length > 1
+ ? tags[1]
+ : firstTag; // Sometimes the first tag is still the community & need to check if there's a second tag
+ tempCategory = tempCategory.startsWith('#')
+ ? tempCategory.substring(1)
+ : tempCategory;
+ }
+
return scheme
.split('{category}')
- .join(post.category)
+ .join(tempCategory)
.split('{username}')
.join(post.author)
.split('{permlink}')
diff --git a/src/app/utils/steemApi.js b/src/app/utils/steemApi.js
index 2f3e5b0a5d..05714f1399 100644
--- a/src/app/utils/steemApi.js
+++ b/src/app/utils/steemApi.js
@@ -8,6 +8,7 @@ export async function callBridge(method, params, pre = 'bridge.') {
//console.log('call bridge');
//console.log("Method: ", method);
//console.log("Params: ", JSON.stringify(params).substring(0, 200));
+ //console.log("Pre: ", pre);
return new Promise(function(resolve, reject) {
api.call(pre + method, params, function(err, data) {
diff --git a/src/server/server-html.jsx b/src/server/server-html.jsx
index 9f6d4f5d52..8cd485eb99 100644
--- a/src/server/server-html.jsx
+++ b/src/server/server-html.jsx
@@ -53,6 +53,7 @@ export default function ServerHTML({
key="canonical"
rel="canonical"
href={m.canonical}
+ id="canonicalUrlID"
/>
);
if (m.name && m.content)
|