diff --git a/package.json b/package.json index bf0f16f..f750c5e 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "prod": "npm run stamp && NODE_ENV=production webpack && cd dist && rm -f ./gitako.zip && zip gitako.zip -r *" }, "dependencies": { + "ini": "^1.3.5", "nprogress": "^0.2.0", "octicons": "^7.1.0", "prop-types": "^15.6.1", diff --git a/src/driver/core/FileExplorer.js b/src/driver/core/FileExplorer.js index d072c9a..6c616b1 100644 --- a/src/driver/core/FileExplorer.js +++ b/src/driver/core/FileExplorer.js @@ -1,7 +1,9 @@ +import ini from 'ini' import DOMHelper from 'utils/DOMHelper' import treeParser from 'utils/treeParser' import URLHelper from 'utils/URLHelper' import VisibleNodesGenerator from 'utils/VisibleNodesGenerator' +import GitHubHelper from 'utils/GitHubHelper' function getVisibleParentNode(nodes, focusedNode, depths) { const focusedNodeIndex = nodes.indexOf(focusedNode) @@ -24,10 +26,37 @@ const init = dispatch => () => dispatch(async () => { dispatch(setStateText, 'Fetching File List...') }) -const setUpTree = dispatch => () => dispatch(async (state, { treeData, metaData, compressSingletonFolder }) => { +function resolveGitModules(root, blobData) { + if (blobData) { + if (blobData.encoding === 'base64') { + const content = atob(blobData.content) + const parsed = ini.parse(content) + Object.values(parsed).map(value => { + const { url, path } = value + // for now, handle modules at root only + const node = root.contents.find(node => node.path === path) + node.url = url + }) + } + } +} + +const setUpTree = dispatch => () => dispatch(async (state, { treeData, metaData, compressSingletonFolder, accessToken }) => { if (!treeData) return dispatch(setStateText, 'Rendering File List...') - const { root } = treeParser.parse(treeData, metaData) + const { root, gitModules } = treeParser.parse(treeData, metaData) + + if (gitModules) { + const blobData = await GitHubHelper.getBlobData({ + userName: metaData.userName, + repoName: metaData.repoName, + fileSHA: gitModules.sha, + accessToken, + }) + + resolveGitModules(root, blobData) + } + visibleNodesGenerator.setCompress(compressSingletonFolder) await visibleNodesGenerator.plantTree(root) @@ -193,16 +222,16 @@ const focusNode = dispatch => (node, skipScroll) => dispatch(({ visibleNodes: { dispatch(updateVisibleNodes) }) -const onNodeClick = dispatch => (node) => { +const onNodeClick = dispatch => (node) => dispatch((state, { metaData, accessToken }) => { if (node.type === 'tree') { dispatch(toggleNodeExpansion, node, true) } else if (node.type === 'blob') { dispatch(focusNode, node, true) DOMHelper.loadWithPJAX(node.url) } else if (node.type === 'commit') { - DOMHelper.loadWithPJAX(node.parent.url) + window.open(node.url, '_blank') } -} +}) const mountExpandingIndicator = dispatch => node => dispatch(({ visibleNodes }) => { const dummyVisibleNodes = { diff --git a/src/utils/GitHubHelper.js b/src/utils/GitHubHelper.js index ccf1c36..aab2694 100644 --- a/src/utils/GitHubHelper.js +++ b/src/utils/GitHubHelper.js @@ -26,6 +26,11 @@ async function getTreeData({ userName, repoName, branchName, accessToken }) { return await request(url, { accessToken }) } +async function getBlobData({ userName, repoName, accessToken, fileSHA }) { + const url = `https://api.github.com/repos/${userName}/${repoName}/git/blobs/${fileSHA}` + return await request(url, { accessToken }) +} + function getUrlForRedirect({ userName, repoName, branchName }, type = 'blob', path) { return `https://github.com/${userName}/${repoName}/${type}/${branchName}/${path}` } @@ -33,5 +38,6 @@ function getUrlForRedirect({ userName, repoName, branchName }, type = 'blob', pa export default { getRepoMeta, getTreeData, + getBlobData, getUrlForRedirect, } diff --git a/src/utils/treeParser.js b/src/utils/treeParser.js index 2ebbe62..69ec360 100644 --- a/src/utils/treeParser.js +++ b/src/utils/treeParser.js @@ -30,6 +30,16 @@ function setParentNode(root, parent = null) { } } +function findGitModules(root) { + if (root.contents) { + const modulesFile = root.contents.find(content => content.name === '.gitmodules') + if (modulesFile) { + return modulesFile + } + } + return null +} + function parse(treeData, metaData) { const { tree } = treeData @@ -71,7 +81,9 @@ function parse(treeData, metaData) { }) setParentNode(root) + return { + gitModules: findGitModules(root), root: sortFoldersToFront(root), } } diff --git a/yarn.lock b/yarn.lock index 0febcce..ae9c87a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2913,7 +2913,7 @@ inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" -ini@~1.3.0: +ini@^1.3.5, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"