Merge branch 'develop'

This commit is contained in:
EnixCoda 2020-02-08 23:59:01 +08:00
commit 38e250dbb3
No known key found for this signature in database
GPG key ID: 0C1A07377913A1DD
16 changed files with 154 additions and 58 deletions

View file

@ -19,9 +19,9 @@ Yet another extension for GitHub, available on both Chrome and Firefox. Inspired
[![Install for Chrome](./ChromeWebStoreBadge.svg)](https://chrome.google.com/webstore/detail/gitako-github-file-tree/giljefjcheohhamkjphiebfjnlphnokk)
[Or install for Firefox](https://addons.mozilla.org/en-US/firefox/addon/gitako-github-file-tree/)
[for Edge](https://microsoftedge.microsoft.com/addons/detail/alpoloddcggjhakjemghahlkofjekbca)
> Gitako for Firefox is still in beta
[for Firefox(beta)](https://addons.mozilla.org/en-US/firefox/addon/gitako-github-file-tree/)
### Issues

View file

@ -1,6 +1,6 @@
{
"name": "gitako",
"version": "0.8.2",
"version": "0.8.7",
"description": "The missing part of GitHub.",
"repository": "https://github.com/EnixCoda/Gitako",
"author": "EnixCoda",
@ -56,8 +56,8 @@
"json-loader": "^0.5.7",
"less": "^3.9.0",
"less-loader": "^4.0.5",
"mini-css-extract-plugin": "^0.9.0",
"raw-loader": "^4.0.0",
"style-loader": "^0.23.1",
"typescript": "^3.7.2",
"uglifyjs-webpack-plugin": "^2.1.2",
"url-loader": "^1.1.2",

View file

@ -5,13 +5,45 @@ import { IN_PRODUCTION_MODE, VERSION } from 'env'
const PUBLIC_KEY = 'd22ec5c9cc874539a51c78388c12e3b0'
const PROJECT_ID = '1406497'
const MAX_REPORT_COUNT = 10 // protect for error leaking
let countReportedError = 0
const errorSet = new Set<string>([
'inThisSearch is null', // weird bug in Firefox
'The quota has been exceeded.', // caused by other addons in Firefox
'NetworkError when attempting to fetch resource.', // network fail in Firefox
'Failed to fetch', // network fail in Chrome
])
const sentryOptions: Sentry.BrowserOptions = {
dsn: `https://${PUBLIC_KEY}@sentry.io/${PROJECT_ID}`,
release: VERSION,
environment: IN_PRODUCTION_MODE ? 'production' : 'development',
// Not safe to activate all integrations in non-Chrome environments where Gitako may not run in top context
// https://docs.sentry.io/platforms/javascript/#sdk-integrations
integrations: ints => ints.filter(({ name }) => name !== 'TryCatch'),
defaultIntegrations: IN_PRODUCTION_MODE ? undefined : false,
integrations: integrations => integrations.filter(({ name }) => name !== 'TryCatch'),
beforeSend(event) {
const message = event.exception?.values?.[0].value || event.message
if (message) {
if (errorSet.has(message)) return null
errorSet.add(message) // prevent reporting duplicated error
}
if (countReportedError < MAX_REPORT_COUNT) {
++countReportedError
return event
}
return null
},
beforeBreadcrumb(breadcrumb, hint) {
if (breadcrumb.category === 'ui.click') {
const ariaLabel = hint?.event?.target?.ariaLabel
if (ariaLabel) {
breadcrumb.message = ariaLabel
}
}
return breadcrumb
},
}
Sentry.init(sentryOptions)

View file

@ -6,7 +6,7 @@ import { connect } from 'driver/connect'
import { FileExplorerCore } from 'driver/core'
import { ConnectorState, Props } from 'driver/core/FileExplorer'
import * as React from 'react'
import { useEvent } from 'react-use'
import useEvent from 'react-use/esm/useEvent'
import { FixedSizeList as List, ListChildComponentProps, ListProps } from 'react-window'
import { cx } from 'utils/cx'
import { useOnLocationChange, usePrevious } from 'utils/hooks'

View file

@ -125,16 +125,19 @@ type Props = {
}
export function Icon({ type, className = undefined, placeholder, ...otherProps }: Props) {
if (placeholder) return <div className={cx('octicon-wrapper')} />
const { name, IconComponent } = getSVGIconComponent(type)
const mergedClassName = cx('octicon', name)
let children: React.ReactNode = null
if (!placeholder) {
const { name, IconComponent } = getSVGIconComponent(type)
const mergedClassName = cx('octicon', name)
children = React.createElement(Octicon, {
icon: IconComponent,
className: mergedClassName,
verticalAlign: 'text-bottom',
})
}
return (
<div className={cx('octicon-wrapper', className)} {...otherProps}>
{React.createElement(Octicon, {
icon: IconComponent,
className: mergedClassName,
verticalAlign: 'text-bottom',
})}
{children}
</div>
)
}

View file

@ -77,14 +77,19 @@ const NodeItemIcon = React.memo(function NodeItemIcon({
val: { icons },
} = useConfigs()
if (icons === 'native') return <Icon type={getIconType(node)} />
const src = React.useMemo(
() => (node.type === 'tree' ? getFolderIconSrc(node, open) : getFileIconSrc(node)),
[open],
)
if (icons === 'native') return <Icon type={getIconType(node)} />
return (
<>
<Icon placeholder={node.type !== 'tree'} type={getIconType(node)} />
<Icon
className={'node-item-type-icon'}
placeholder={node.type !== 'tree'}
type={getIconType(node)}
/>
{node.type === 'commit' ? (
<Icon type={getIconType(node)} />
) : (

View file

@ -1,14 +0,0 @@
import * as React from 'react'
import * as DOMHelper from 'utils/DOMHelper'
type Props<P> = {
to: string
children: React.ReactElement<P>
}
export function PJAXLink<P>({ to, children }: Props<P>) {
return React.cloneElement(children, {
...children.props,
onClick: () => DOMHelper.loadWithPJAX(to),
})
}

View file

@ -11,7 +11,7 @@ import { SideBarCore } from 'driver/core'
import { ConnectorState, Props } from 'driver/core/SideBar'
import { oauth } from 'env'
import * as React from 'react'
import { useEvent } from 'react-use'
import useEvent from 'react-use/esm/useEvent'
import { cx } from 'utils/cx'
import * as DOMHelper from 'utils/DOMHelper'
import { JSONRequest, parseURLSearch } from 'utils/general'
@ -85,7 +85,7 @@ const RawGitako: React.FC<Props & ConnectorState> = function RawGitako(props) {
// init again when setting new accessToken
useDidUpdate(() => {
props.init()
}, [accessToken])
}, [accessToken || '']) // fallback for preventing duplicated requests
const {
errorDueToAuth,

View file

@ -358,12 +358,29 @@
transition: all 0.5s ease;
white-space: nowrap;
&-icon {
.icon-size() {
width: 16px;
height: 16px;
}
.octicon-wrapper:first-child {
margin-right: 6px;
}
&-type-icon {
margin-right: 4px;
.icon-size();
& + .octicon-wrapper,
& + .node-item-icon {
margin-right: 6px;
}
}
&-icon {
.icon-size();
object-fit: contain;
vertical-align: text-bottom;
padding-left: 4px;
box-sizing: content-box;
&.dim {
@ -379,12 +396,9 @@
.node-item-label {
overflow: hidden;
text-overflow: ellipsis;
.node-item-name {
padding-left: 6px;
}
}
.node-item:hover .node-item-name {
&:hover .node-item-name {
text-decoration: underline;
}

View file

@ -7,7 +7,14 @@ import './content.less'
addMiddleware(withErrorLog)
const SideBarElement = document.createElement('div')
document.body.appendChild(SideBarElement)
function init() {
const SideBarElement = document.createElement('div')
document.body.appendChild(SideBarElement)
ReactDOM.render(<Gitako />, SideBarElement)
}
ReactDOM.render(<Gitako />, SideBarElement)
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init)
} else {
init()
}

View file

@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Gitako - Github file tree",
"version": "0.8.2",
"version": "0.8.7",
"description": "The missing part of GitHub.",
"author": "EnixCoda",
"icons": {
@ -21,6 +21,9 @@
"matches": [
"https://github.com/*"
],
"css": [
"content.css"
],
"js": [
"firefox-shim.js",
"browser-polyfill.js",

View file

@ -10,7 +10,7 @@ export function parse(): MetaData & { path: string[] } {
repoName,
type,
...path // should be [...branchName.split('/'), ...filePath.split('/')]
] = pathname.split('/')
] = unescape(decodeURIComponent(pathname)).split('/')
return {
userName,
repoName,
@ -80,7 +80,10 @@ export function getCurrentPath(branchName = '') {
splitBranchName.shift()
path.shift()
} else {
raiseError(new Error(`branch name and path prefix not match`))
raiseError(new Error(`branch name and path prefix not match`), {
branchName,
path: parse().path,
})
return []
}
}

View file

@ -1,5 +1,5 @@
import * as React from 'react'
import { useLocation } from 'react-use'
import useLocation from 'react-use/esm/useLocation'
import { createStyleSheet, setStyleSheetMedia } from './general'
export function useWindowSize(

View file

@ -65,10 +65,14 @@ export function getFileIconSrc(node: TreeNode) {
return getIconSrc('file', iconName)
}
// memorize for
// 1. swap time with space
// 2. prevent app crash on when extension context invalidates
const extensionURL = browser.runtime.getURL('').replace(/\/$/, '')
export function getIconSrc(type: 'folder' | 'file', name: string = 'default', open?: boolean) {
const filename =
(name === 'default' ? 'default_' + type : type + '_type_' + name) +
(open ? '_opened' : '') +
'.svg'
return browser.runtime.getURL(`icons/vscode/${filename}`)
return extensionURL + `/icons/vscode/${filename}`
}

View file

@ -3,6 +3,7 @@ const CopyWebpackPlugin = require('copy-webpack-plugin')
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
const path = require('path')
const Dotenv = require('dotenv-webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const srcPath = path.resolve(__dirname, 'src')
@ -33,6 +34,7 @@ const plugins = [
]),
new ForkTsCheckerWebpackPlugin(),
new Dotenv(),
new MiniCssExtractPlugin(),
]
const analyse = process.env.ANALYSE !== undefined
@ -75,7 +77,7 @@ module.exports = {
},
{
test: /\.less$/,
loader: ['style-loader', 'css-loader', 'less-loader'],
loader: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'],
include: [srcPath],
},
{

View file

@ -4685,7 +4685,7 @@ is-path-inside@^1.0.0:
dependencies:
path-is-inside "^1.0.1"
is-plain-obj@^1.1.0:
is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
@ -5373,6 +5373,16 @@ mimic-response@^1.0.0, mimic-response@^1.0.1:
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
mini-css-extract-plugin@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e"
integrity sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==
dependencies:
loader-utils "^1.1.0"
normalize-url "1.9.1"
schema-utils "^1.0.0"
webpack-sources "^1.1.0"
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
@ -5707,6 +5717,16 @@ normalize-path@^3.0.0:
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
normalize-url@1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c"
integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=
dependencies:
object-assign "^4.0.1"
prepend-http "^1.0.0"
query-string "^4.1.0"
sort-keys "^1.0.0"
normalize-url@^4.1.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
@ -6248,6 +6268,11 @@ prelude-ls@~1.1.2:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
prepend-http@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
prepend-http@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
@ -6405,6 +6430,14 @@ qs@~6.5.1, qs@~6.5.2:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
query-string@^4.1.0:
version "4.3.4"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb"
integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s=
dependencies:
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
querystring-es3@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
@ -7185,6 +7218,13 @@ sonic-boom@^0.7.5:
dependencies:
flatstr "^1.0.12"
sort-keys@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad"
integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0=
dependencies:
is-plain-obj "^1.0.0"
source-list-map@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
@ -7395,6 +7435,11 @@ stream-to-promise@2.2.0:
end-of-stream "~1.1.0"
stream-to-array "~2.3.0"
strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
@ -7517,14 +7562,6 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
style-loader@^0.23.1:
version "0.23.1"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925"
integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==
dependencies:
loader-utils "^1.1.0"
schema-utils "^1.0.0"
stylis@3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.0.tgz#016fa239663d77f868fef5b67cf201c4b7c701e1"
@ -8202,7 +8239,7 @@ webpack-log@^2.0.0:
ansi-colors "^3.0.0"
uuid "^3.3.2"
webpack-sources@^1.4.0, webpack-sources@^1.4.1:
webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1:
version "1.4.3"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933"
integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==