vzcode
Version:
Multiplayer code editor system
180 lines (164 loc) • 4.01 kB
text/typescript
import { VZAction, VZState } from '.';
import {
SearchFile,
SearchFileVisibility,
SearchResult,
ShareDBDoc,
} from '../../types';
import { VizContent } from '@vizhub/viz-types';
function searchPattern(
shareDBDoc: ShareDBDoc<VizContent>,
pattern: string,
): SearchResult {
const files = shareDBDoc.data.files;
const fileIds = Object.keys(shareDBDoc.data.files);
let results: { [id: string]: SearchFile } = {};
for (let i = 0; i < fileIds.length; i++) {
const file = files[fileIds[i]];
if (files[fileIds[i]].text) {
const fileName = file.name;
const lines = file.text.split('\n');
const matches = [];
for (let j = 0; j < lines.length; j++) {
const index = lines[j].indexOf(pattern);
if (index !== -1) {
matches.push({
line: j + 1,
index: index,
text: lines[j],
isClosed: false,
});
}
}
if (matches.length > 0) {
results[fileIds[i]] = {
name: fileName,
matches: matches,
visibility: 'open',
};
}
}
}
return results;
}
function updateSearchFileVisibility(
results: SearchResult,
id: string,
visibility: SearchFileVisibility,
): SearchResult {
return {
...results,
[id]: { ...results[id], visibility: visibility },
};
}
export const setIsSearchOpenReducer = (
state: VZState,
action: VZAction,
): VZState =>
action.type === 'set_is_search_open'
? { ...state, isSearchOpen: action.value }
: state;
export const setSearchReducer = (
state: VZState,
action: VZAction,
): VZState =>
action.type === 'set_search'
? {
...state,
search: {
...state.search,
pattern: action.value,
results: {},
focusedIndex: 0,
focusedChildIndex: null,
focused: true,
},
}
: state;
export const setSearchResultsReducer = (
state: VZState,
action: VZAction,
): VZState =>
action.type === 'set_search_results'
? {
...state,
search: {
...state.search,
pattern: state.search.pattern,
results: searchPattern(
action.files,
state.search.pattern,
),
focused: state.search.focused,
},
}
: state;
export const setSearchFileVisibilityReducer = (
state: VZState,
action: VZAction,
): VZState =>
action.type === 'set_search_file_visibility'
? {
...state,
search: {
...state.search,
pattern: state.search.pattern,
results: updateSearchFileVisibility(
state.search.results,
action.id,
action.visibility,
),
},
}
: state;
export const setSearchLineVisibilityReducer = (
state: VZState,
action: VZAction,
): VZState =>
action.type === 'hide_search_results_line'
? {
...state,
search: {
...state.search,
results: {
...state.search.results,
[action.id]: {
...state.search.results[action.id],
matches: state.search.results[
action.id
].matches.filter(
(match, index) =>
match.line !== action.line,
),
},
},
},
}
: state;
export const setSearchFocusedIndexReducer = (
state: VZState,
action: VZAction,
): VZState =>
action.type === 'set_active_search_index'
? {
...state,
search: {
...state.search,
focusedIndex: action.focusedIndex,
focusedChildIndex: action.childIndex,
},
}
: state;
export const toggleSearchFocusedReducer = (
state: VZState,
action: VZAction,
): VZState =>
action.type === 'toggle_search_focused'
? {
...state,
search: {
...state.search,
focused: !state.search.focused,
},
}
: state;