@@ -4,7 +4,7 @@ import {connect} from 'react-redux';
44import log from './log' ;
55
66import { setProjectTitle } from '../reducers/project-title' ;
7- import { setAuthor , setDescription } from '../reducers/tw' ;
7+ import { setAuthor , setDescription , resetViews , setViews } from '../reducers/tw' ;
88
99export const fetchProjectMeta = async projectId => {
1010 const urls = [
@@ -32,6 +32,30 @@ export const fetchProjectMeta = async projectId => {
3232 throw firstError ;
3333} ;
3434
35+ const fetchWindchimes = async projectId => {
36+ try {
37+ const url = `https://windchimes.turbowarp.org/api/scratch/${ projectId } ` ;
38+ const res = await fetch ( url ) ;
39+
40+ if ( ! res . ok ) {
41+ return null ;
42+ }
43+
44+ const data = await res . json ( ) ;
45+
46+ // Windchimes returns dates in terms of days since 2000
47+ const epoch = Date . UTC ( 2000 , 0 , 1 ) ;
48+ const first = new Date ( epoch + ( data . firstDate * 60 * 60 * 24 * 1000 ) ) ;
49+
50+ return {
51+ total : data . total ,
52+ first
53+ } ;
54+ } catch ( e ) {
55+ return null ;
56+ }
57+ } ;
58+
3559const getNoIndexTag = ( ) => document . querySelector ( 'meta[name="robots"][content="noindex"]' ) ;
3660const setIndexable = indexable => {
3761 if ( indexable ) {
@@ -54,48 +78,80 @@ const TWProjectMetaFetcherHOC = function (WrappedComponent) {
5478 if ( this . props . reduxProjectId !== prevProps . reduxProjectId ) {
5579 this . props . onSetAuthor ( '' , '' ) ;
5680 this . props . onSetDescription ( '' , '' ) ;
81+ this . props . onResetViews ( ) ;
82+
5783 const projectId = this . props . reduxProjectId ;
84+ if ( projectId !== '0' ) {
85+ this . tryFetchAuthorDescription ( this . props . reduxProjectId ) ;
86+ this . tryFetchViews ( this . props . reduxProjectId ) ;
87+ }
88+ }
89+ }
5890
59- if ( projectId === '0' ) {
60- // don't try to get metadata
61- } else {
62- fetchProjectMeta ( projectId ) . then ( data => {
63- // If project ID changed, ignore the results.
64- if ( this . props . reduxProjectId !== projectId ) {
65- return ;
66- }
67-
68- const title = data . title ;
69- if ( title ) {
70- this . props . onSetProjectTitle ( title ) ;
71- }
72- const authorName = data . author . username ;
73- const authorThumbnail = `https://trampoline.turbowarp.org/avatars/${ data . author . id } ` ;
74- this . props . onSetAuthor ( authorName , authorThumbnail ) ;
75- const instructions = data . instructions || '' ;
76- const credits = data . description || '' ;
77- if ( instructions || credits ) {
78- this . props . onSetDescription ( instructions , credits ) ;
79- }
80- setIndexable ( true ) ;
81- } )
82- . catch ( err => {
83- setIndexable ( false ) ;
84- if ( `${ err } ` . includes ( 'unshared' ) ) {
85- this . props . onSetDescription ( 'unshared' , 'unshared' ) ;
86- }
87- log . warn ( 'cannot fetch project meta' , err ) ;
88- } ) ;
91+ async tryFetchAuthorDescription ( projectId ) {
92+ try {
93+ const data = await fetchProjectMeta ( projectId ) ;
94+
95+ if ( this . props . reduxProjectId !== projectId ) {
96+ // If project ID changed, ignore the results.
97+ return ;
8998 }
99+
100+ const title = data . title ;
101+ if ( title ) {
102+ this . props . onSetProjectTitle ( title ) ;
103+ }
104+ const authorName = data . author . username ;
105+ const authorThumbnail = `https://trampoline.turbowarp.org/avatars/${ data . author . id } ` ;
106+ this . props . onSetAuthor ( authorName , authorThumbnail ) ;
107+
108+ const instructions = data . instructions || '' ;
109+ const credits = data . description || '' ;
110+ if ( instructions || credits ) {
111+ this . props . onSetDescription ( instructions , credits ) ;
112+ }
113+
114+ setIndexable ( true ) ;
115+ } catch ( err ) {
116+ if ( `${ err } ` . includes ( 'unshared' ) ) {
117+ this . props . onSetDescription ( 'unshared' , 'unshared' ) ;
118+ }
119+
120+ setIndexable ( false ) ;
121+
122+ log . warn ( 'cannot fetch project meta' , err ) ;
123+ }
124+ }
125+
126+ async tryFetchViews ( projectId ) {
127+ try {
128+ const data = await fetchWindchimes ( projectId ) ;
129+
130+ if ( this . props . reduxProjectId !== projectId ) {
131+ // If project ID changed, ignore the results.
132+ return ;
133+ }
134+
135+ if ( ! data ) {
136+ // No view information available
137+ return ;
138+ }
139+
140+ this . props . onSetViews ( data . total , data . first ) ;
141+ } catch ( err ) {
142+ log . warn ( 'cannot fetch windchimes' , err ) ;
90143 }
91144 }
145+
92146 render ( ) {
93147 const {
94148 /* eslint-disable no-unused-vars */
95149 reduxProjectId,
96150 onSetAuthor,
97151 onSetDescription,
98152 onSetProjectTitle,
153+ onResetViews,
154+ onSetViews,
99155 /* eslint-enable no-unused-vars */
100156 ...props
101157 } = this . props ;
@@ -110,7 +166,9 @@ const TWProjectMetaFetcherHOC = function (WrappedComponent) {
110166 reduxProjectId : PropTypes . string ,
111167 onSetAuthor : PropTypes . func ,
112168 onSetDescription : PropTypes . func ,
113- onSetProjectTitle : PropTypes . func
169+ onSetProjectTitle : PropTypes . func ,
170+ onResetViews : PropTypes . func ,
171+ onSetViews : PropTypes . func
114172 } ;
115173 const mapStateToProps = state => ( {
116174 reduxProjectId : state . scratchGui . projectState . projectId
@@ -124,7 +182,9 @@ const TWProjectMetaFetcherHOC = function (WrappedComponent) {
124182 instructions,
125183 credits
126184 } ) ) ,
127- onSetProjectTitle : title => dispatch ( setProjectTitle ( title ) )
185+ onSetProjectTitle : title => dispatch ( setProjectTitle ( title ) ) ,
186+ onResetViews : ( ) => dispatch ( resetViews ( ) ) ,
187+ onSetViews : ( total , first ) => dispatch ( setViews ( total , first ) )
128188 } ) ;
129189 return connect (
130190 mapStateToProps ,
0 commit comments