mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-04-29 04:45:19 +08:00
chore: configure bob and metro
This commit is contained in:
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": ["react-native"]
|
|
||||||
}
|
|
||||||
@@ -21,8 +21,8 @@ jobs:
|
|||||||
- v1-dependencies-example-{{ checksum "example/package.json" }}
|
- v1-dependencies-example-{{ checksum "example/package.json" }}
|
||||||
- v1-dependencies-example-
|
- v1-dependencies-example-
|
||||||
- run: |
|
- run: |
|
||||||
yarn install
|
yarn install --frozen-lockfile
|
||||||
yarn install --cwd example
|
yarn install --frozen-lockfile --cwd example
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: v1-dependencies-{{ checksum "package.json" }}
|
key: v1-dependencies-{{ checksum "package.json" }}
|
||||||
paths: node_modules
|
paths: node_modules
|
||||||
@@ -44,10 +44,16 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- attach_workspace:
|
- attach_workspace:
|
||||||
at: ~/project
|
at: ~/project
|
||||||
- run: yarn test -- --coverage
|
- run: yarn test --coverage
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: coverage
|
path: coverage
|
||||||
destination: coverage
|
destination: coverage
|
||||||
|
build:
|
||||||
|
<<: *defaults
|
||||||
|
steps:
|
||||||
|
- attach_workspace:
|
||||||
|
at: ~/project
|
||||||
|
- run: yarn prepare
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
version: 2
|
version: 2
|
||||||
@@ -60,3 +66,6 @@ workflows:
|
|||||||
- unit-tests:
|
- unit-tests:
|
||||||
requires:
|
requires:
|
||||||
- install-dependencies
|
- install-dependencies
|
||||||
|
- build:
|
||||||
|
requires:
|
||||||
|
- install-dependencies
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
coverage/
|
||||||
jest-setup.js
|
lib/
|
||||||
|
|||||||
3
packages/stack/.gitignore
vendored
3
packages/stack/.gitignore
vendored
@@ -51,3 +51,6 @@ android/keystores/debug.keystore
|
|||||||
|
|
||||||
# Build
|
# Build
|
||||||
dist/
|
dist/
|
||||||
|
|
||||||
|
# generated by bob
|
||||||
|
lib/
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"increment": "conventional:angular",
|
"increment": "conventional:angular",
|
||||||
"changelogCommand": "conventional-changelog -p angular | tail -n +3",
|
"scripts": {
|
||||||
"safeBump": false,
|
"changelog": "conventional-changelog -p angular | tail -n +3"
|
||||||
"src": {
|
},
|
||||||
|
"git": {
|
||||||
"commitMessage": "chore: release %s",
|
"commitMessage": "chore: release %s",
|
||||||
"tagName": "v%s"
|
"tagName": "v%s"
|
||||||
},
|
},
|
||||||
|
|||||||
5
packages/stack/babel.config.js
Normal file
5
packages/stack/babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/* eslint-disable import/no-commonjs */
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
presets: ['module:metro-react-native-babel-preset'],
|
||||||
|
};
|
||||||
5
packages/stack/commitlint.config.js
Normal file
5
packages/stack/commitlint.config.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/* eslint-disable import/no-commonjs */
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
extends: ['@commitlint/config-conventional'],
|
||||||
|
};
|
||||||
@@ -1,5 +1,12 @@
|
|||||||
{
|
{
|
||||||
"presets": [
|
"presets": [
|
||||||
"expo"
|
"expo"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
["module-resolver", {
|
||||||
|
"alias": {
|
||||||
|
"react-navigation-stack": "../src/index"
|
||||||
|
}
|
||||||
|
}]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
{
|
{
|
||||||
"extends": "../.eslintrc",
|
'extends': '../.eslintrc',
|
||||||
|
|
||||||
"settings": {
|
'settings':
|
||||||
"import/core-modules": [ "expo", "react-navigation-stack" ]
|
{
|
||||||
},
|
'import/core-modules':
|
||||||
|
[
|
||||||
|
'react-navigation-stack',
|
||||||
|
'react-native-gesture-handler',
|
||||||
|
'react-native-vector-icons',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
"rules": {
|
"rules": {
|
||||||
"react/prop-types": "off"
|
"react-native/no-inline-styles": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
"slug": "react-navigation-stack-demo",
|
"slug": "react-navigation-stack-demo",
|
||||||
"sdkVersion": "32.0.0",
|
"sdkVersion": "32.0.0",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"primaryColor": "#2196f3"
|
"primaryColor": "#2196f3",
|
||||||
|
"packagerOpts": {
|
||||||
|
"config": "./metro.config.js",
|
||||||
|
"projectRoots": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
35
packages/stack/example/metro.config.js
Normal file
35
packages/stack/example/metro.config.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/* eslint-disable import/no-extraneous-dependencies, import/no-commonjs */
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const blacklist = require('metro-config/src/defaults/blacklist');
|
||||||
|
const project = require('../package.json');
|
||||||
|
const escape = require('escape-string-regexp');
|
||||||
|
|
||||||
|
const projectDependencies = Object.keys({
|
||||||
|
...project.dependencies,
|
||||||
|
...project.peerDependencies,
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
projectRoot: __dirname,
|
||||||
|
watchFolders: [path.resolve(__dirname, '..')],
|
||||||
|
|
||||||
|
resolver: {
|
||||||
|
blacklistRE: blacklist([
|
||||||
|
new RegExp(
|
||||||
|
`^${escape(
|
||||||
|
path.resolve(__dirname, 'node_modules', project.name)
|
||||||
|
)}\\/.*$`
|
||||||
|
),
|
||||||
|
new RegExp(
|
||||||
|
`^${escape(path.resolve(__dirname, '..', 'node_modules'))}\\/.*$`
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
|
||||||
|
providesModuleNodeModules: [
|
||||||
|
'@expo/vector-icons',
|
||||||
|
'@babel/runtime',
|
||||||
|
...projectDependencies,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -6,24 +6,20 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "expo start",
|
"start": "expo start",
|
||||||
"android": "expo start --android",
|
"android": "expo start --android",
|
||||||
"ios": "expo start --ios",
|
"ios": "expo start --ios"
|
||||||
"postinstall": "rm -rf node_modules/react-navigation-stack/{.git,node_modules,example}"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-navigation/core": "^3.3.1",
|
||||||
|
"@react-navigation/native": "^3.4.1",
|
||||||
|
"expo": "32.0.6",
|
||||||
|
"hoist-non-react-statics": "^3.3.0",
|
||||||
"react": "16.5.0",
|
"react": "16.5.0",
|
||||||
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
|
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
|
||||||
"react-native-paper": "^2.2.0",
|
"react-native-paper": "^2.15.2",
|
||||||
"react-navigation-stack": "../",
|
"react-navigation-drawer": "^1.2.1",
|
||||||
"react-navigation-drawer": "^1.1.0",
|
"react-navigation-tabs": "*"
|
||||||
"react-navigation-tabs": "*",
|
|
||||||
"@react-navigation/core": "^3.0.0",
|
|
||||||
"@react-navigation/native": "^3.1.1",
|
|
||||||
"expo": "32.0.0",
|
|
||||||
"hoist-non-react-statics": "^2.5.0",
|
|
||||||
"prop-types": "^15.6.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-plugin-module-resolver": "^3.0.0",
|
"babel-plugin-module-resolver": "^3.2.0"
|
||||||
"glob-to-regexp": "^0.3.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,6 @@
|
|||||||
/**
|
/* eslint-env jest */
|
||||||
* eslint-env jest
|
|
||||||
*/
|
|
||||||
|
|
||||||
jest.mock('react-native-gesture-handler', () => ({
|
jest.mock('react-native-gesture-handler', () => ({
|
||||||
PanGestureHandler: 'PanGestureHandler',
|
PanGestureHandler: 'PanGestureHandler',
|
||||||
BaseButton: 'BaseButton',
|
BaseButton: 'BaseButton',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
|
|||||||
@@ -2,24 +2,22 @@
|
|||||||
"name": "react-navigation-stack",
|
"name": "react-navigation-stack",
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"description": "Stack navigator component for React Navigation",
|
"description": "Stack navigator component for React Navigation",
|
||||||
"main": "dist/index.js",
|
"main": "lib/commonjs/index.js",
|
||||||
"module": "src/index.web.js",
|
"module": "lib/module/index.js",
|
||||||
|
"react-native": "src/index.js",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"files": [
|
"files": [
|
||||||
"dist/",
|
"src",
|
||||||
"src/",
|
"lib"
|
||||||
"LICENSE.md",
|
|
||||||
"README.md"
|
|
||||||
],
|
],
|
||||||
"react-native": "src/index.js",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"format": "eslint . --fix",
|
"format": "eslint . --fix",
|
||||||
"build": "babel --no-babelrc --plugins=syntax-jsx,syntax-class-properties,syntax-object-rest-spread,transform-flow-strip-types src --copy-files --out-dir dist --ignore '**/__tests__/**'",
|
"prepare": "bob build",
|
||||||
"dev": "yarn build --watch --out-dir example/node_modules/react-navigation-stack/dist",
|
"release": "release-it",
|
||||||
"prepare": "yarn build",
|
"example": "yarn --cwd example",
|
||||||
"release": "release-it"
|
"bootstrap": "yarn && yarn example"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"registry": "https://registry.npmjs.org/"
|
"registry": "https://registry.npmjs.org/"
|
||||||
@@ -43,30 +41,28 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/react-navigation/react-navigation-stack#readme",
|
"homepage": "https://github.com/react-navigation/react-navigation-stack#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@expo/vector-icons": "^6.2.0",
|
"@babel/core": "^7.4.3",
|
||||||
"@react-navigation/core": "^3.0.0",
|
"@commitlint/config-conventional": "^7.5.0",
|
||||||
"@react-navigation/native": "^3.0.0",
|
"@expo/vector-icons": "^10.0.1",
|
||||||
"babel-cli": "^6.26.0",
|
"@react-native-community/bob": "^0.3.4",
|
||||||
"babel-jest": "^22.4.1",
|
"@react-navigation/core": "^3.3.1",
|
||||||
"babel-plugin-syntax-class-properties": "^6.13.0",
|
"@react-navigation/native": "^3.4.1",
|
||||||
"babel-plugin-syntax-jsx": "^6.18.0",
|
"commitlint": "^7.5.2",
|
||||||
"babel-plugin-syntax-object-rest-spread": "^6.13.0",
|
"conventional-changelog-cli": "^2.0.12",
|
||||||
"babel-plugin-transform-flow-strip-types": "^6.22.0",
|
"eslint": "^5.16.0",
|
||||||
"babel-preset-react-native": "^4.0.0",
|
"eslint-config-satya164": "^2.4.1",
|
||||||
"conventional-changelog-cli": "^2.0.5",
|
|
||||||
"eslint": "^4.12.1",
|
|
||||||
"eslint-config-satya164": "^1.0.1",
|
|
||||||
"eslint-plugin-react-native-globals": "^0.1.0",
|
"eslint-plugin-react-native-globals": "^0.1.0",
|
||||||
"husky": "^0.14.3",
|
"husky": "^1.3.1",
|
||||||
"jest": "^23.6.0",
|
"jest": "^24.7.1",
|
||||||
"prettier": "^1.8.2",
|
"prettier": "^1.17.0",
|
||||||
"react": "16.6.3",
|
"react": "16.5.0",
|
||||||
"react-dom": "16.3.3",
|
"react-dom": "16.5.0",
|
||||||
"react-native": "^0.57.7",
|
"react-native": "~0.57.7",
|
||||||
"react-native-gesture-handler": "^1.0.8",
|
"react-native-gesture-handler": "^1.1.0",
|
||||||
"react-native-screens": "^1.0.0-alpha",
|
"react-native-screens": "^1.0.0-alpha.22",
|
||||||
"react-test-renderer": "16.6.3",
|
"react-test-renderer": "16.5.0",
|
||||||
"release-it": "^7.6.1"
|
"release-it": "^10.4.2",
|
||||||
|
"scheduler": "^0.14.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@react-navigation/core": "^3.0.0",
|
"@react-navigation/core": "^3.0.0",
|
||||||
@@ -86,7 +82,8 @@
|
|||||||
"jest-setup.js"
|
"jest-setup.js"
|
||||||
],
|
],
|
||||||
"modulePathIgnorePatterns": [
|
"modulePathIgnorePatterns": [
|
||||||
"<rootDir>/example/"
|
"<rootDir>/example/",
|
||||||
|
"<rootDir>/lib/"
|
||||||
],
|
],
|
||||||
"transformIgnorePatterns": [
|
"transformIgnorePatterns": [
|
||||||
"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|react-navigation-deprecated-tab-navigator|@react-navigation/core|@react-navigation/native)"
|
"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|react-navigation-deprecated-tab-navigator|@react-navigation/core|@react-navigation/native)"
|
||||||
@@ -95,5 +92,19 @@
|
|||||||
"prettier": {
|
"prettier": {
|
||||||
"trailingComma": "es5",
|
"trailingComma": "es5",
|
||||||
"singleQuote": true
|
"singleQuote": true
|
||||||
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "yarn lint && yarn test",
|
||||||
|
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@react-native-community/bob": {
|
||||||
|
"source": "src",
|
||||||
|
"output": "lib",
|
||||||
|
"targets": [
|
||||||
|
"commonjs",
|
||||||
|
"module"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,63 +1,41 @@
|
|||||||
/* eslint-disable import/no-commonjs */
|
|
||||||
import { Platform } from 'react-native';
|
import { Platform } from 'react-native';
|
||||||
|
|
||||||
module.exports = {
|
/**
|
||||||
/**
|
* Navigators
|
||||||
* Navigators
|
*/
|
||||||
*/
|
export {
|
||||||
get createStackNavigator() {
|
default as createStackNavigator,
|
||||||
return require('./navigators/createStackNavigator').default;
|
} from './navigators/createStackNavigator';
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
export const Assets = Platform.select({
|
||||||
* Views
|
ios: [
|
||||||
*/
|
require('./views/assets/back-icon.png'),
|
||||||
get Assets() {
|
require('./views/assets/back-icon-mask.png'),
|
||||||
return Platform.select({
|
],
|
||||||
ios: [
|
default: [require('./views/assets/back-icon.png')],
|
||||||
require('./views/assets/back-icon.png'),
|
});
|
||||||
require('./views/assets/back-icon-mask.png'),
|
|
||||||
],
|
/**
|
||||||
default: [require('./views/assets/back-icon.png')],
|
* Views
|
||||||
});
|
*/
|
||||||
},
|
export { default as Header } from './views/Header/Header';
|
||||||
get Header() {
|
export { default as HeaderBackButton } from './views/Header/HeaderBackButton';
|
||||||
return require('./views/Header/Header').default;
|
export { default as HeaderTitle } from './views/Header/HeaderTitle';
|
||||||
},
|
export {
|
||||||
get HeaderBackButton() {
|
default as HeaderStyleInterpolator,
|
||||||
return require('./views/Header/HeaderBackButton').default;
|
} from './views/Header/HeaderStyleInterpolator';
|
||||||
},
|
export { default as StackView } from './views/StackView/StackView';
|
||||||
get HeaderTitle() {
|
export { default as StackViewCard } from './views/StackView/StackViewCard';
|
||||||
return require('./views/Header/HeaderTitle').default;
|
export { default as StackViewLayout } from './views/StackView/StackViewLayout';
|
||||||
},
|
export {
|
||||||
get HeaderStyleInterpolator() {
|
default as StackViewStyleInterpolator,
|
||||||
return require('./views/Header/HeaderStyleInterpolator').default;
|
} from './views/StackView/StackViewStyleInterpolator';
|
||||||
},
|
export {
|
||||||
get StackView() {
|
default as StackViewTransitionConfigs,
|
||||||
return require('./views/StackView/StackView').default;
|
} from './views/StackView/StackViewTransitionConfigs';
|
||||||
},
|
export {
|
||||||
get StackViewCard() {
|
default as createPointerEventsContainer,
|
||||||
return require('./views/StackView/StackViewCard').default;
|
} from './views/StackView/createPointerEventsContainer';
|
||||||
},
|
export { default as Transitioner } from './views/Transitioner';
|
||||||
get StackViewLayout() {
|
export { default as ScenesReducer } from './views/ScenesReducer';
|
||||||
return require('./views/StackView/StackViewLayout').default;
|
export { default as StackGestureContext } from './utils/StackGestureContext';
|
||||||
},
|
|
||||||
get StackViewStyleInterpolator() {
|
|
||||||
return require('./views/StackView/StackViewStyleInterpolator').default;
|
|
||||||
},
|
|
||||||
get StackViewTransitionConfigs() {
|
|
||||||
return require('./views/StackView/StackViewTransitionConfigs').default;
|
|
||||||
},
|
|
||||||
get createPointerEventsContainer() {
|
|
||||||
return require('./views/StackView/createPointerEventsContainer').default;
|
|
||||||
},
|
|
||||||
get Transitioner() {
|
|
||||||
return require('./views/Transitioner').default;
|
|
||||||
},
|
|
||||||
get ScenesReducer() {
|
|
||||||
return require('./views/ScenesReducer').default;
|
|
||||||
},
|
|
||||||
get StackGestureContext() {
|
|
||||||
return require('./utils/StackGestureContext').default;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Animated, Platform } from 'react-native';
|
import { Animated, Platform } from 'react-native';
|
||||||
import { BaseButton } from 'react-native-gesture-handler';
|
import { BaseButton } from 'react-native-gesture-handler';
|
||||||
|
|
||||||
const AnimatedBaseButton = Animated.createAnimatedComponent(BaseButton);
|
const AnimatedBaseButton = Animated.createAnimatedComponent(BaseButton);
|
||||||
|
|
||||||
export default class BorderlessButton extends React.Component {
|
export default class BorderlessButton extends React.Component {
|
||||||
static propTypes = {
|
|
||||||
...BaseButton.propTypes,
|
|
||||||
borderless: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
activeOpacity: 0.3,
|
activeOpacity: 0.3,
|
||||||
borderless: true,
|
borderless: true,
|
||||||
|
|||||||
@@ -169,12 +169,14 @@ class Header extends React.PureComponent {
|
|||||||
const onLayout =
|
const onLayout =
|
||||||
layoutPreset === 'center'
|
layoutPreset === 'center'
|
||||||
? e => {
|
? e => {
|
||||||
this.setState({
|
const { width } = e.nativeEvent.layout;
|
||||||
|
|
||||||
|
this.setState(state => ({
|
||||||
widths: {
|
widths: {
|
||||||
...this.state.widths,
|
...state.widths,
|
||||||
[props.scene.key]: e.nativeEvent.layout.width,
|
[props.scene.key]: width,
|
||||||
},
|
},
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
@@ -189,8 +191,10 @@ class Header extends React.PureComponent {
|
|||||||
style={[
|
style={[
|
||||||
color ? { color } : null,
|
color ? { color } : null,
|
||||||
layoutPreset === 'center'
|
layoutPreset === 'center'
|
||||||
? { textAlign: 'center' }
|
? // eslint-disable-next-line react-native/no-inline-styles
|
||||||
: { textAlign: 'left' },
|
{ textAlign: 'center' }
|
||||||
|
: // eslint-disable-next-line react-native/no-inline-styles
|
||||||
|
{ textAlign: 'left' },
|
||||||
titleStyle,
|
titleStyle,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import Transitioner from '../Transitioner';
|
|||||||
|
|
||||||
describe('Transitioner', () => {
|
describe('Transitioner', () => {
|
||||||
// TODO: why does this fail here but not when it was part of react-navigation repo?
|
// TODO: why does this fail here but not when it was part of react-navigation repo?
|
||||||
xit('should not trigger onTransitionStart and onTransitionEnd when route params are changed', () => {
|
it.skip('should not trigger onTransitionStart and onTransitionEnd when route params are changed', () => {
|
||||||
const onTransitionStartCallback = jest.fn();
|
const onTransitionStartCallback = jest.fn();
|
||||||
const onTransitionEndCallback = jest.fn();
|
const onTransitionEndCallback = jest.fn();
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user