Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Jul 7, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 30 additions & 19 deletions app/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,21 @@ export function wrapFiles (links) {
/**
* This function will allow the user to add a file or multiple files to the IPFS repo.
* Accepts a string or a string array.
* Wraps the files in a directory.
* Wraps the files in a directory (if it's not disabled in the settings).
*
* ```
* Wrapper {
* Result {
* hash: string;
* path: string;
* size: number;
* }
* ```
*
* @param {string[]} filePaths
* @returns {Promise<Wrapper>} promise resolving with the wrapper
* @param {boolean} forceWrapping - if true it will wrap the files regardless of the user settings
* @returns {Promise<Result>} promise resolving with the wrapper or the file
*/
export function addFilesFromFSPath (filePaths, _queryGateways = queryGateways) {
export function addFilesFromFSPath (filePaths, forceWrapping = false, _queryGateways = queryGateways) {
if (!IPFS_CLIENT) return Promise.reject(ERROR_IPFS_UNAVAILABLE)
trackEvent('addFilesFromFSPath', { count: filePaths.length })

Expand Down Expand Up @@ -173,7 +174,6 @@ export function addFilesFromFSPath (filePaths, _queryGateways = queryGateways) {
// IPFS_CLIENT.util.addFromFs always returns an array
// (because it can upload an dir recursively),
// which is why we expect an array of arrays

const rootFiles = fileUploadResults.map(result => {
/**
* If it was a directory it will be last
Expand All @@ -192,29 +192,40 @@ export function addFilesFromFSPath (filePaths, _queryGateways = queryGateways) {
return result[result.length - 1]
})

return wrapFiles(rootFiles)
.then(wrapper => Promise.all([
// This value is needed further in the chain
wrapper,
// Pin the wrapper directory
IPFS_CLIENT.pin.add(wrapper.hash),
// Unpin the initial uploads
...rootFiles.map(rootFile => IPFS_CLIENT.pin.rm(rootFile.hash))
]))
return Promise.resolve(forceWrapping ? false : Settings.get('disableWrapping'))
.then(disableWrapping => {
/**
* Skip wrapping the files if the user disable this feature
*/
if (disableWrapping) return Promise.resolve()

return wrapFiles(rootFiles)
.then(wrapper => Promise.all([
// This value is needed further in the chain
wrapper,
// Pin the wrapper directory
IPFS_CLIENT.pin.add(wrapper.hash),
// Unpin the initial uploads
...rootFiles.map(rootFile => IPFS_CLIENT.pin.rm(rootFile.hash))
]))
})
/**
* Query the gateways and return the wrapper dir
* Query the gateways and return the wrapper dir or the rootFiles
*/
.then(results => {
const wrapper = results[0]
const wrapper = results ? results[0] : null

if (!Settings.get('skipGatewayQuery')) {
// Query all the uploaded files
fileUploadResults.forEach(files => files.forEach(file => _queryGateways(file.hash)))
// Query the wrapper
_queryGateways(wrapper.hash)
// Query the wrapper if it exists
if (wrapper) {
_queryGateways(wrapper.hash)
}
}

return Promise.resolve(wrapper)
// Return the wrapper if it exists, otherwise the rootFiles last item
return Promise.resolve(wrapper || rootFiles[rootFiles.length - 1])
})
})
.catch(reportAndReject)
Expand Down
31 changes: 11 additions & 20 deletions app/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,13 @@ jest.mock('request-promise-native', () => {

jest.mock('electron-settings', () => {
const getMock = jest.fn()
// get('disableWrapping')
.mockReturnValueOnce(false)
// get('skipGatewayQuery')
.mockReturnValueOnce(true)
// get('disableWrapping')
.mockReturnValueOnce(true)
// get('skipGatewayQuery')
.mockReturnValueOnce(false)
return {
get: getMock
Expand Down Expand Up @@ -272,7 +277,7 @@ describe('api.js', () => {
})
const queryGatewaysMock = jest.fn()
// act
return api.addFilesFromFSPath(['./textfiles'], queryGatewaysMock)
return api.addFilesFromFSPath(['./textfiles'], false, queryGatewaysMock)
.then(result => {
// assert
expect(addFromFsMock).toHaveBeenCalledWith('./textfiles', {
Expand All @@ -298,7 +303,7 @@ describe('api.js', () => {
})
})

it('should add the file/dir recursively and query the gateways', () => {
it('should add the file/dir recursively without wrapper and query the gateways', () => {
// arrange
// arrange
const addFromFsMock = jest.fn()
Expand All @@ -315,39 +320,25 @@ describe('api.js', () => {
]))

const objectPutMock = jest.fn()
.mockReturnValue(Promise.resolve({
toJSON: () => {
return {
multihash: 'QmRgutAxd8t7oGkSm4wmeuByG6M51wcTso6cubDdQtu003',
size: 60
}
}
}))

const pinAddMock = jest.fn().mockReturnValue(Promise.resolve())
const pinRmMock = jest.fn().mockReturnValue(Promise.resolve())

api.setClientInstance({
util: {
addFromFs: addFromFsMock
},
object: {
put: objectPutMock
},
pin: {
add: pinAddMock,
rm: pinRmMock
}
})
const queryGatewaysMock = jest.fn()
// act
return api.addFilesFromFSPath(['./textfiles'], queryGatewaysMock)
return api.addFilesFromFSPath(['./textfiles'], false, queryGatewaysMock)
.then(result => {
// assert
expect(result.hash).toEqual('QmRgutAxd8t7oGkSm4wmeuByG6M51wcTso6cubDdQtu002')
expect(objectPutMock).not.toHaveBeenCalled()
expect(queryGatewaysMock).toHaveBeenCalledWith('QmRgutAxd8t7oGkSm4wmeuByG6M51wcTso6cubDdQtu001')
expect(queryGatewaysMock).toHaveBeenCalledWith('QmRgutAxd8t7oGkSm4wmeuByG6M51wcTso6cubDdQtu002')
expect(queryGatewaysMock).toHaveBeenCalledWith('QmRgutAxd8t7oGkSm4wmeuByG6M51wcTso6cubDdQtu003')
expect(queryGatewaysMock).toHaveBeenCalledTimes(3)
expect(queryGatewaysMock).toHaveBeenCalledTimes(2)
})
})
})
Expand Down
47 changes: 40 additions & 7 deletions app/windows/Settings/Components/IntegrationsPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,36 @@ import { observer } from 'mobx-react'
import { Pane, CheckBox } from 'react-photonkit'
import * as ContextMenu from '../../../lib/os-context-menu/index'
import Settings from 'electron-settings'
import styled from 'styled-components'

const isWindows = process.platform === 'win32'

const WrappingSetting = styled.div`
.checkbox {
margin-bottom: 0px;
}

p {
margin-top: 0px;
color: rgb(127,127,127);
font-style: italic;
}
`

@observer
class IntegrationsPanel extends React.Component {
state = {
contextMenu: false
contextMenu: false,
disableWrapping: false
}

componentDidMount () {
ContextMenu.isRegistered().then(status => {
this.setState({ contextMenu: status })
})

const disableWrapping = Settings.get('disableWrapping')
this.setState({ disableWrapping })
}

_handleContextMenuChange = () => {
Expand All @@ -32,19 +49,35 @@ class IntegrationsPanel extends React.Component {
}
}

_handleWrappingChange = () => {
const nextValue = !this.state.disableWrapping
Settings.set('disableWrapping', nextValue)
this.setState({ disableWrapping: nextValue })
}

render () {
if (this.props.navigationStore.selected !== 3) return null
if (!this.props.informationStore) return null
if (!this.props.informationStore.loaded) return null
if (!isWindows) return null

return (
<Pane className="settings">
<CheckBox
label='Enable "Add to IPFS" option to files and folders'
checked={this.state.contextMenu}
onChange={this._handleContextMenuChange}
/>
{
isWindows &&
<CheckBox
label='Enable "Add to IPFS" option to files and folders'
checked={this.state.contextMenu}
onChange={this._handleContextMenuChange}
/>
}
<WrappingSetting>
<CheckBox
label='Enable wrapping when adding a file'
checked={!this.state.disableWrapping}
onChange={this._handleWrappingChange}
/>
<p>Wrapping a file will help preserving file names and extensions</p>
</WrappingSetting>
</Pane>
)
}
Expand Down
11 changes: 2 additions & 9 deletions app/windows/Settings/Components/Sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { observer } from 'mobx-react'

import { Pane, NavGroup, NavTitle, NavGroupItem } from 'react-photonkit'

const isWindows = process.platform === 'win32'

/**
* Render the Sidebar, uses NavigatorStore
*/
Expand All @@ -19,15 +17,10 @@ class Sidebar extends React.Component {
<NavTitle key='title'>Settings and Info</NavTitle>,
<NavGroupItem key='con' glyph="rss" text="Connectivity" eventKey={0} />,
<NavGroupItem key='rep' glyph="database" text="Repository" eventKey={1} />,
<NavGroupItem key='peers' glyph="users" text="Peers" eventKey={2} />
<NavGroupItem key='peers' glyph="users" text="Peers" eventKey={2} />,
<NavGroupItem key='integrations' glyph="tools" text="Integrations" eventKey={3} />
]

if (isWindows) {
menus.push(
<NavGroupItem key='integrations' glyph="tools" text="Integrations" eventKey={3} />
)
}

return (
<Pane sidebar ptSize="sm">
<NavGroup onSelect={this._handleSelect}>
Expand Down
2 changes: 1 addition & 1 deletion app/windows/Storage/fileIntegration.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function addFilesPaths (paths) {
let promises
if (paths.length > 1 && askWhetherToWrapAllFiles()) {
// If the user says yes to wrapping all files, simply pass the paths array
promises = [addFilesFromFSPath(paths)]
promises = [addFilesFromFSPath(paths, true)]
} else {
// User wants to wrap each file (this method expects an array)
promises = paths.map(path => addFilesFromFSPath([path]))
Expand Down