diff --git a/README.md b/README.md index 9dd2df6..fa6cda5 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Here is an example from the Web: * [J. F. Kennedy](https://pewu.github.io/topola-viewer/#/view?url=https%3A%2F%2Fchronoplexsoftware.com%2Fmyfamilytree%2Fsamples%2FThe%2520Kennedy%2520Family.gdz) (from [chronoplexsoftware.com](https://chronoplexsoftware.com/myfamilytree/samples/)) * [Shakespeare](https://pewu.github.io/topola-viewer/#/view?url=https%3A%2F%2Fwebtreeprint.com%2Ftp_downloader.php%3Fpath%3Dfamous_gedcoms%2Fshakespeare.ged%26file%3Dshakespeare.ged) (from [webtreeprint.com](https://webtreeprint.com/tp_famous_gedcoms.php)) -* [Maria Skłodowska-Curie](https://pewu.github.io/topola-viewer/#/view?indi=Sk%C5%82odowska-2&source=wikitree) (from [WikiTree](https://www.wikitree.com/wiki/Sk%C5%82odowska-2)) +* [Maria Skłodowska-Curie](https://apps.wikitree.com/apps/wiech13/topola-viewer/#/view?indi=Sk%C5%82odowska-2&source=wikitree) (from [WikiTree](https://www.wikitree.com/wiki/Sk%C5%82odowska-2)) If you have data in a genealogy database, you can export your data in GEDCOM format and load it using the "Load from file" menu. diff --git a/src/datasource/wikitree_api.ts b/src/datasource/wikitree_api.ts index 086a2e0..9f3327d 100644 --- a/src/datasource/wikitree_api.ts +++ b/src/datasource/wikitree_api.ts @@ -6,6 +6,7 @@ import { Person, } from 'wikitree-js'; import {TopolaError} from '../util/error'; +import {isOnWikitreeDomain} from '../util/wikitree_util'; const WIKITREE_APP_ID = 'topola-viewer'; /** Prefix for IDs of private individuals. */ @@ -270,7 +271,7 @@ export async function loadData( authcode?: string, ): Promise { // Work around CORS if not in apps.wikitree.com domain. - const handleCors = window.location.hostname !== 'apps.wikitree.com'; + const handleCors = !isOnWikitreeDomain(); await logInIfNeeded(authcode, handleCors); diff --git a/src/intro.tsx b/src/intro.tsx index 0d48a8b..2ce2a7a 100644 --- a/src/intro.tsx +++ b/src/intro.tsx @@ -6,6 +6,7 @@ import {Card, Grid, Image} from 'semantic-ui-react'; import {getChangelog, updateSeenVersion} from './changelog'; import logo from './topola.jpg'; import {Media} from './util/media'; +import {isOnWikitreeDomain, WIKITREE_TOPOLA_URL} from './util/wikitree_util'; /** Link that loads a view. */ function ViewLink(props: {params: {[key: string]: string}; text: string}) { @@ -82,13 +83,23 @@ function Contents() { )
  • - {' '} + {isOnWikitreeDomain() ? ( + + ) : ( + + Maria Skłodowska-Curie ↗ + + )}{' '} ({' '} wikitree.com diff --git a/src/menu/top_bar.tsx b/src/menu/top_bar.tsx index 00f0ab7..6837c51 100644 --- a/src/menu/top_bar.tsx +++ b/src/menu/top_bar.tsx @@ -5,6 +5,7 @@ import {Dropdown, Icon, Menu} from 'semantic-ui-react'; import {IndiInfo, JsonGedcomData} from 'topola'; import {isGoogleDriveConfigured} from '../datasource/google_drive_service'; import {Media} from '../util/media'; +import {isOnWikitreeDomain} from '../util/wikitree_util'; import {GoogleDriveMenu} from './google_drive_menu'; import {MenuItem, MenuType} from './menu_item'; import {SearchBar} from './search'; @@ -50,6 +51,11 @@ export function TopBar(props: Props) { const navigate = useNavigate(); const location = useLocation(); + // WikiTree menus only work when hosted on apps.wikitree.com because + // WikiTree's API requires same-origin access. The CORS proxy workaround is + // no longer functional. + const showWikiTree = props.showWikiTreeMenus && isOnWikitreeDomain(); + const {searchResults, searchString, setSearchString, handleResultSelect} = useSearch({ data: props.data, @@ -246,7 +252,7 @@ export function TopBar(props: Props) { <> - + {showWikiTree && } ; @@ -307,7 +313,7 @@ export function TopBar(props: Props) { } function wikiTreeLoginMenu(screenSize: ScreenSize) { - if (!props.showWikiTreeMenus) { + if (!showWikiTree) { return null; } return ( diff --git a/src/menu/wikitree_menu.tsx b/src/menu/wikitree_menu.tsx index a3fa706..6d62e15 100644 --- a/src/menu/wikitree_menu.tsx +++ b/src/menu/wikitree_menu.tsx @@ -5,6 +5,7 @@ import {useLocation, useNavigate} from 'react-router'; import {Button, Form, Header, Input, Modal} from 'semantic-ui-react'; import {getLoggedInUserName, navigateToLoginPage} from 'wikitree-js'; import {analyticsEvent} from '../util/analytics'; +import {WIKITREE_TOPOLA_URL} from '../util/wikitree_util'; import {MenuItem, MenuType} from './menu_item'; import wikitreeLogo from './wikitree.png'; @@ -157,10 +158,8 @@ export function WikiTreeLoginMenu(props: Props) { * Topola Viewer hosted on apps.wikitree.com. */ function login() { - const wikiTreeTopolaUrl = - 'https://apps.wikitree.com/apps/wiech13/topola-viewer'; // TODO: remove authcode if it is in the current URL. - const returnUrl = `${wikiTreeTopolaUrl}${window.location.hash}`; + const returnUrl = `${WIKITREE_TOPOLA_URL}${window.location.hash}`; navigateToLoginPage(returnUrl); } diff --git a/src/util/wikitree_util.ts b/src/util/wikitree_util.ts new file mode 100644 index 0000000..9511740 --- /dev/null +++ b/src/util/wikitree_util.ts @@ -0,0 +1,17 @@ +/** + * Base URL for Topola Viewer hosted on apps.wikitree.com. + * WikiTree API calls only work when the app is served from this domain. + */ +export const WIKITREE_TOPOLA_URL = + 'https://apps.wikitree.com/apps/wiech13/topola-viewer'; + +/** + * Returns true if the app is currently hosted on the apps.wikitree.com domain. + * + * WikiTree's API requires being served from this domain due to authentication + * and CORS restrictions. When not on this domain, WikiTree data loading does + * not work. + */ +export function isOnWikitreeDomain(): boolean { + return window.location.hostname === 'apps.wikitree.com'; +}