diff --git a/components/settings.js b/components/settings.js index cfce6da..13ac320 100644 --- a/components/settings.js +++ b/components/settings.js @@ -3,12 +3,11 @@ import { View, Button, Text, - ScrollView + ScrollView, + Alert } from 'react-native' import Share from 'react-native-share' -import { Base64 } from 'js-base64' -import objectPath from 'object-path' -import { getColumnNamesForCsv, cycleDaysSortedByDate } from '../db' +import getDataAsCsvDataUri from '../lib/export-to-csv' import styles from '../styles/index' export default class Settings extends Component { @@ -28,9 +27,17 @@ export default class Settings extends Component { ) } -} - -function makeDataURI(cycleDays) { - const csv = transformToCsv(cycleDays) - const encoded = Base64.encodeURI(csv) - return `data:text/csv;base64,${encoded}` -} - -function transformToCsv(cycleDays) { - const columnNames = getColumnNamesForCsv() - const rows = cycleDays - .map(day => { - return columnNames.map(column => { - const val = objectPath.get(day, column, '') - return typeof val === 'string' ? csvify(val) : val - }) - }) - .map(row => row.join(',')) - - rows.unshift(columnNames.join(',')) - return rows.join('\n') -} - -function csvify (val) { - // escape double quotes - val = val.replace(/"/g, '""') - - val = val.toLowerCase() - const hasSpecialChars = ( - val.includes('\n') || - val.includes('\t') || - val.includes(',') || - val.includes(';') || - val.includes('.') || - val.includes('\'') - ) - - return hasSpecialChars ? `"${val}"` : val } \ No newline at end of file diff --git a/lib/export-to-csv.js b/lib/export-to-csv.js new file mode 100644 index 0000000..56bc4c5 --- /dev/null +++ b/lib/export-to-csv.js @@ -0,0 +1,45 @@ +import objectPath from 'object-path' +import { Base64 } from 'js-base64' + +import { getColumnNamesForCsv, cycleDaysSortedByDate } from '../db' + +export default function makeDataURI() { + if (!cycleDaysSortedByDate.length) return null + + const csv = transformToCsv(cycleDaysSortedByDate) + const encoded = Base64.encodeURI(csv) + return `data:text/csv;base64,${encoded}` +} + +function transformToCsv(cycleDays) { + const columnNames = getColumnNamesForCsv() + const rows = cycleDays + .map(day => { + return columnNames.map(column => { + const val = objectPath.get(day, column) + return typeof val === 'string' ? csvify(val) : val + }) + }) + .map(row => row.join(',')) + + rows.unshift(columnNames.join(',')) + return rows.join('\n') +} + +function csvify (val) { + // we wrap fields with special characters in quotes, + // thus have to escape actual quotes + val = val.replace(/"/g, '""') + + val = val.toLowerCase() + const hasSpecialChars = ( + val.includes('\n') || + val.includes('\t') || + val.includes(',') || + val.includes(';') || + val.includes('.') || + val.includes('\'') + ) + + return hasSpecialChars ? `"${val}"` : val +} \ No newline at end of file