Fixes Issue #12421 - Change page title based on the site section being viewed (#12627)

* Update title for tabs not including challenges, guild and team

* add section titles to challenges, guilds, and groups

* Update dynamic title to use vuex action

* Remove duplicate key

* Actually remove duplicate key

* Fix section sub section in group

* Add note to implement setTitle when adding a page

* Add missing sections to dynamic title

* Features string not translated

* Use onGroupUpdate to update group titles

* Add watcher to challenges for dynamic title updates

* Small fixes

* Add register and login to title, remove duplicate keys

* Add home page dynamic title functionality

* Minor name changes

* remove wrong i18n strings from front.js

* refactor router note

Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
This commit is contained in:
jbusa22
2020-10-26 06:22:46 -04:00
committed by GitHub
parent 869d2df4fa
commit ad51675ac6
36 changed files with 188 additions and 6 deletions

View File

@@ -745,6 +745,7 @@ export default {
watch: { watch: {
$route: { $route: {
handler () { handler () {
this.setTitle();
if (this.resetPasswordSetNewOne) { if (this.resetPasswordSetNewOne) {
const { query } = this.$route; const { query } = this.$route;
const { code } = query; const { code } = query;
@@ -760,7 +761,6 @@ export default {
this.$router.push({ name: 'login' }); this.$router.push({ name: 'login' });
return; return;
} }
this.resetPasswordSetNewOneData.code = query.code; this.resetPasswordSetNewOneData.code = query.code;
this.resetPasswordSetNewOneData.hasError = hasError; this.resetPasswordSetNewOneData.hasError = hasError;
} }
@@ -898,6 +898,18 @@ export default {
window.location.href = redirectTo; window.location.href = redirectTo;
} }
}, },
setTitle () {
if (this.resetPasswordSetNewOne) {
return;
}
let title = 'login';
if (this.registering) {
title = 'register';
}
this.$store.dispatch('common:setTitle', {
section: this.$t(title),
});
},
handleSubmit () { handleSubmit () {
if (this.registering) { if (this.registering) {
this.register(); this.register();

View File

@@ -384,6 +384,16 @@ export default {
memberResults: [], memberResults: [],
}; };
}, },
watch: {
'challenge.name': {
handler (newVal) {
this.$store.dispatch('common:setTitle', {
section: this.$t('challenge'),
subSection: newVal.name,
});
},
},
},
computed: { computed: {
...mapState({ user: 'user.data' }), ...mapState({ user: 'user.data' }),
isMember () { isMember () {
@@ -433,6 +443,10 @@ export default {
this.$router.push('/challenges/findChallenges'); this.$router.push('/challenges/findChallenges');
return; return;
} }
this.$store.dispatch('common:setTitle', {
subSection: this.challenge.name,
section: this.$t('challenges'),
});
const tasks = await this.$store.dispatch('tasks:getChallengeTasks', { challengeId: this.searchId }); const tasks = await this.$store.dispatch('tasks:getChallengeTasks', { challengeId: this.searchId });
this.tasksByType = { this.tasksByType = {
habit: [], habit: [],

View File

@@ -175,6 +175,10 @@ export default {
}, },
}, },
mounted () { mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('findChallenges'),
section: this.$t('challenges'),
});
this.loadChallenges(); this.loadChallenges();
}, },
methods: { methods: {

View File

@@ -218,6 +218,10 @@ export default {
}, },
}, },
mounted () { mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('myChallenges'),
section: this.$t('challenges'),
});
this.loadChallenges(); this.loadChallenges();
}, },
methods: { methods: {

View File

@@ -224,7 +224,10 @@ export default {
this.group = await this.$store.dispatch('guilds:getGroup', { this.group = await this.$store.dispatch('guilds:getGroup', {
groupId: this.searchId, groupId: this.searchId,
}); });
this.$store.dispatch('common:setTitle', {
subSection: this.group.name,
section: this.$t('group'),
});
const members = await this.$store.dispatch('members:getGroupMembers', { groupId: this.searchId }); const members = await this.$store.dispatch('members:getGroupMembers', { groupId: this.searchId });
this.group.members = members; this.group.members = members;

View File

@@ -155,6 +155,12 @@ export default {
return this.guilds.filter(guild => filterGuild(guild, filters, search, user)); return this.guilds.filter(guild => filterGuild(guild, filters, search, user));
}, },
}, },
mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('guildsDiscovery'),
section: this.$t('guilds'),
});
},
methods: { methods: {
async updateSearch (eventData) { async updateSearch (eventData) {
// this.search = eventData.searchTerm; @TODO: Probably don't need this anymore // this.search = eventData.searchTerm; @TODO: Probably don't need this anymore

View File

@@ -500,7 +500,10 @@ export default {
if (this.isParty) this.searchId = 'party'; if (this.isParty) this.searchId = 'party';
if (!this.searchId) this.searchId = this.groupId; if (!this.searchId) this.searchId = this.groupId;
await this.fetchGuild(); await this.fetchGuild();
this.$store.dispatch('common:setTitle', {
section: this.$t('groupPlans'),
subSection: this.group.name,
});
this.$root.$on('updatedGroup', this.onGroupUpdate); this.$root.$on('updatedGroup', this.onGroupUpdate);
}, },
beforeDestroy () { beforeDestroy () {
@@ -508,7 +511,6 @@ export default {
}, },
beforeRouteUpdate (to, from, next) { beforeRouteUpdate (to, from, next) {
this.$set(this, 'searchId', to.params.groupId); this.$set(this, 'searchId', to.params.groupId);
next(); next();
}, },
methods: { methods: {
@@ -518,6 +520,10 @@ export default {
onGroupUpdate (group) { onGroupUpdate (group) {
const updatedGroup = extend(this.group, group); const updatedGroup = extend(this.group, group);
this.$set(this.group, updatedGroup); this.$set(this.group, updatedGroup);
this.$store.dispatch('common:setTitle', {
section: this.$t('groupPlans'),
subSection: group.name,
});
}, },
/** /**

View File

@@ -486,6 +486,9 @@ export default {
}, },
mounted () { mounted () {
this.activePage = this.PAGES.BENEFITS; this.activePage = this.PAGES.BENEFITS;
this.$store.dispatch('common:setTitle', {
section: this.$t('groupPlans'),
});
}, },
methods: { methods: {
launchModal () { launchModal () {

View File

@@ -165,6 +165,12 @@ export default {
}); });
}, },
}, },
mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('myGuilds'),
section: this.$t('guilds'),
});
},
created () { created () {
this.fetchGuilds(); this.fetchGuilds();
}, },

View File

@@ -843,6 +843,10 @@ export default {
}, },
}, },
async mounted () { async mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('tavern'),
section: this.$t('guilds'),
});
this.group = await this.$store.dispatch('guilds:getGroup', { groupId: TAVERN_ID }); this.group = await this.$store.dispatch('guilds:getGroup', { groupId: TAVERN_ID });
}, },
methods: { methods: {

View File

@@ -508,6 +508,11 @@ export default {
this.costumeMode = getLocalSetting( this.costumeMode = getLocalSetting(
CONSTANTS.keyConstants.CURRENT_EQUIPMENT_DRAWER_TAB, CONSTANTS.keyConstants.CURRENT_EQUIPMENT_DRAWER_TAB,
) === CONSTANTS.equipmentDrawerTabValues.COSTUME_TAB; ) === CONSTANTS.equipmentDrawerTabValues.COSTUME_TAB;
this.$store.dispatch('common:setTitle', {
subSection: this.$t('equipment'),
section: this.$t('inventory'),
});
}, },
methods: { methods: {
selectDrawerTab (tabName) { selectDrawerTab (tabName) {

View File

@@ -491,6 +491,12 @@ export default {
return this.groups.some(g => g.selected); return this.groups.some(g => g.selected);
}, },
}, },
mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('items'),
section: this.$t('inventory'),
});
},
watch: { watch: {
searchText: throttle(function throttleSearch () { searchText: throttle(function throttleSearch () {
this.searchTextThrottled = this.searchText.toLowerCase(); this.searchTextThrottled = this.searchText.toLowerCase();

View File

@@ -645,6 +645,12 @@ export default {
return Object.values(this.viewOptions).some(g => g.selected); return Object.values(this.viewOptions).some(g => g.selected);
}, },
}, },
mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('stable'),
section: this.$t('inventory'),
});
},
watch: { watch: {
searchText: _throttle(function throttleSearch () { searchText: _throttle(function throttleSearch () {
const search = this.searchText.toLowerCase(); const search = this.searchText.toLowerCase();

View File

@@ -154,6 +154,10 @@ export default {
}, },
}, },
mounted () { mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('settings'),
subSection: this.$t('API'),
});
window.addEventListener('message', this.receiveMessage, false); window.addEventListener('message', this.receiveMessage, false);
}, },
destroy () { destroy () {

View File

@@ -13,3 +13,14 @@
</div> </div>
</div> </div>
</template> </template>
<script>
export default {
mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('settings'),
subSection: this.$t('dataExport'),
});
},
};
</script>

View File

@@ -105,6 +105,10 @@ export default {
...mapState({ user: 'user.data' }), ...mapState({ user: 'user.data' }),
}, },
async mounted () { async mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('settings'),
subSection: this.$t('notifications'),
});
// If ?unsubFrom param is passed with valid email type, // If ?unsubFrom param is passed with valid email type,
// automatically unsubscribe users from that email and // automatically unsubscribe users from that email and
// show an alert // show an alert

View File

@@ -87,6 +87,12 @@ export default {
return '/api/v4/coupons'; return '/api/v4/coupons';
}, },
}, },
mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('settings'),
subSection: this.$t('promoCode'),
});
},
methods: { methods: {
generateCodes () { generateCodes () {
// $http.post(ApiUrl.get() + '/api/v2/coupons/generate/ // $http.post(ApiUrl.get() + '/api/v2/coupons/generate/

View File

@@ -678,6 +678,11 @@ export default {
this.emailUpdates.newEmail = this.user.auth.local.email || null; this.emailUpdates.newEmail = this.user.auth.local.email || null;
this.localAuth.username = this.user.auth.local.username || null; this.localAuth.username = this.user.auth.local.username || null;
this.soundIndex = 0; this.soundIndex = 0;
this.$store.dispatch('common:setTitle', {
section: this.$t('settings'),
});
hello.init({ hello.init({
facebook: process.env.FACEBOOK_KEY, // eslint-disable-line no-process-env facebook: process.env.FACEBOOK_KEY, // eslint-disable-line no-process-env
google: process.env.GOOGLE_CLIENT_ID, // eslint-disable-line no-process-env google: process.env.GOOGLE_CLIENT_ID, // eslint-disable-line no-process-env

View File

@@ -720,6 +720,12 @@ export default {
return moment(this.user.purchased.plan.dateTerminated).format('MM/DD/YYYY'); return moment(this.user.purchased.plan.dateTerminated).format('MM/DD/YYYY');
}, },
}, },
mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('settings'),
subSection: this.$t('subscription'),
});
},
methods: { methods: {
async applyCoupon (coupon) { async applyCoupon (coupon) {
const response = await axios.post(`/api/v4/coupons/validate/${coupon}`); const response = await axios.post(`/api/v4/coupons/validate/${coupon}`);

View File

@@ -304,6 +304,10 @@ export default {
}, 250), }, 250),
}, },
async mounted () { async mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('market'),
section: this.$t('shops'),
});
await this.$store.dispatch('worldState:getWorldState'); await this.$store.dispatch('worldState:getWorldState');
}, },
methods: { methods: {

View File

@@ -544,6 +544,10 @@ export default {
}, 250), }, 250),
}, },
async mounted () { async mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('quests'),
section: this.$t('shops'),
});
await this.$store.dispatch('worldState:getWorldState'); await this.$store.dispatch('worldState:getWorldState');
}, },
methods: { methods: {

View File

@@ -517,6 +517,11 @@ export default {
}, 250), }, 250),
}, },
async mounted () { async mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('seasonalShop'),
section: this.$t('shops'),
});
this.$root.$on('buyModal::boughtItem', () => { this.$root.$on('buyModal::boughtItem', () => {
this.backgroundUpdate = new Date(); this.backgroundUpdate = new Date();
}); });

View File

@@ -399,6 +399,10 @@ export default {
}, 250), }, 250),
}, },
mounted () { mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('timeTravelers'),
section: this.$t('shops'),
});
this.$root.$on('buyModal::boughtItem', () => { this.$root.$on('buyModal::boughtItem', () => {
this.backgroundUpdate = new Date(); this.backgroundUpdate = new Date();
}); });

View File

@@ -67,5 +67,10 @@ export default {
goToModForm(this.user); goToModForm(this.user);
}, },
}, },
mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('contactUs'),
});
},
}; };
</script> </script>

View File

@@ -112,6 +112,12 @@ export default {
// "webFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.fandom.com/wiki/FAQ), come ask in the <%= linkStart %>Habitica Help guild<%= linkEnd %>! We're happy to help." // "webFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.fandom.com/wiki/FAQ), come ask in the <%= linkStart %>Habitica Help guild<%= linkEnd %>! We're happy to help."
}; };
}, },
mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('help'),
subSection: this.$t('faq'),
});
},
methods: { methods: {
isVisible (heading) { isVisible (heading) {
return this.visible && this.visible === heading; return this.visible && this.visible === heading;

View File

@@ -137,6 +137,11 @@ export default {
directives: { directives: {
markdown: markdownDirective, markdown: markdownDirective,
}, },
mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('features'),
});
},
methods: { methods: {
playButtonClick () { playButtonClick () {
this.$router.push('/register'); this.$router.push('/register');

View File

@@ -274,6 +274,9 @@ export default {
// Load external scripts after the app has been rendered // Load external scripts after the app has been rendered
setupPayments(); setupPayments();
}); });
this.$store.dispatch('common:setTitle', {
section: this.$t('groupPlans'),
});
}, },
methods: { methods: {
goToNewGroupPage () { goToNewGroupPage () {

View File

@@ -909,6 +909,9 @@ export default {
// windows: WINDOWS_CLIENT_ID, // windows: WINDOWS_CLIENT_ID,
google: process.env.GOOGLE_CLIENT_ID, // eslint-disable-line google: process.env.GOOGLE_CLIENT_ID, // eslint-disable-line
}); });
this.$store.dispatch('common:setTitle', {
fullTitle: 'Habitica - Gamify Your Life',
});
}, },
methods: { methods: {
// eslint-disable-next-line func-names // eslint-disable-next-line func-names

View File

@@ -172,5 +172,10 @@ export default {
], ],
}); });
}, },
mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('presskit'),
});
},
}; };
</script> </script>

View File

@@ -491,6 +491,11 @@ export default {
return tagsByType; return tagsByType;
}, },
}, },
mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('tasks'),
});
},
watch: { watch: {
searchText: throttle(function throttleSearch () { searchText: throttle(function throttleSearch () {
this.searchTextThrottled = this.searchText.toLowerCase(); this.searchTextThrottled = this.searchText.toLowerCase();

View File

@@ -893,6 +893,10 @@ export default {
selectPage (page) { selectPage (page) {
this.selectedPage = page || 'profile'; this.selectedPage = page || 'profile';
window.history.replaceState(null, null, ''); window.history.replaceState(null, null, '');
this.$store.dispatch('common:setTitle', {
section: this.$t('user'),
subSection: this.$t(this.startingPage),
});
}, },
getProgressDisplay () { getProgressDisplay () {
// let currentLoginDay = Content.loginIncentives[this.user.loginIncentives]; // let currentLoginDay = Content.loginIncentives[this.user.loginIncentives];

View File

@@ -781,6 +781,9 @@ export default {
}, },
}, },
async mounted () { async mounted () {
this.$store.dispatch('common:setTitle', {
section: this.$t('messages'),
});
// notification click to refresh // notification click to refresh
this.$root.$on(EVENTS.PM_REFRESH, async () => { this.$root.$on(EVENTS.PM_REFRESH, async () => {
await this.reload(); await this.reload();

View File

@@ -107,6 +107,8 @@ const router = new VueRouter({
return { x: 0, y: 0 }; return { x: 0, y: 0 };
}, },
// requiresLogin is true by default, isStatic false // requiresLogin is true by default, isStatic false
// NOTE: when adding a new route entry make sure to implement the `common:setTitle` action
// in the route component to set a specific subtitle for the page.
routes: [ routes: [
{ {
name: 'register', path: '/register', component: RegisterLoginReset, meta: { requiresLogin: false }, name: 'register', path: '/register', component: RegisterLoginReset, meta: { requiresLogin: false },

View File

@@ -23,6 +23,16 @@ export function hatch (store, params) {
// .catch((err) => console.error('equip', err)); // .catch((err) => console.error('equip', err));
} }
export function setTitle (store, params) {
if (params.subSection && params.section) {
store.state.title = `${params.subSection} | ${params.section} | Habitica`;
} else if (params.section) {
store.state.title = `${params.section} | Habitica`;
} else if (params.fullTitle) {
store.state.title = params.fullTitle;
}
}
export async function feed (store, params) { export async function feed (store, params) {
const user = store.state.user.data; const user = store.state.user.data;
feedOp(user, { params }); feedOp(user, { params });

View File

@@ -15,7 +15,6 @@
"emailNewPass": "Email a Password Reset Link", "emailNewPass": "Email a Password Reset Link",
"forgotPasswordSteps": "Enter the email address you used to register your Habitica account.", "forgotPasswordSteps": "Enter the email address you used to register your Habitica account.",
"sendLink": "Send Link", "sendLink": "Send Link",
"featuredIn": "Featured in",
"footerDevs": "Developers", "footerDevs": "Developers",
"footerCommunity": "Community", "footerCommunity": "Community",
"footerCompany": "Company", "footerCompany": "Company",

View File

@@ -48,6 +48,7 @@
"memberList": "Member List", "memberList": "Member List",
"invited": "Invited", "invited": "Invited",
"name": "Name", "name": "Name",
"features": "Features",
"description": "Description", "description": "Description",
"public": "Public", "public": "Public",
"inviteOnly": "Invite Only", "inviteOnly": "Invite Only",
@@ -136,7 +137,6 @@
"gemGiftsAreOptional": "Please note that Habitica will never require you to gift gems to other players. Begging people for gems is a <strong>violation of the Community Guidelines</strong>, and all such instances should be reported to <%= hrefTechAssistanceEmail %>.", "gemGiftsAreOptional": "Please note that Habitica will never require you to gift gems to other players. Begging people for gems is a <strong>violation of the Community Guidelines</strong>, and all such instances should be reported to <%= hrefTechAssistanceEmail %>.",
"battleWithFriends": "Battle Monsters With Friends", "battleWithFriends": "Battle Monsters With Friends",
"startAParty": "Start a Party", "startAParty": "Start a Party",
"possessiveParty": "<%= name %>'s Party",
"partyUpName": "Party Up", "partyUpName": "Party Up",
"partyOnName": "Party On", "partyOnName": "Party On",
"partyUpText": "Joined a Party with another person! Have fun battling monsters and supporting each other.", "partyUpText": "Joined a Party with another person! Have fun battling monsters and supporting each other.",