Anesthesia

This is a mobile app, made with React Native, meant for the Android and iOS markets. It is 99% ready, but it's not yet available, because of administrative delays on the part of the client.

It is a handbook for MSD pharmaceutical company. The main feature is a small search engine, allowing the user to quickly and easily locate the chapter and subchapter with the desired information. The key words are also highlighetd in the text.

I joined at a late stage of the development process. The app was initially started by two other developers who left the project and I had to pick it up from there.

My task was to modify some of the existing features, as well as to add a few new ones. It was also my responsibility to prepare the final builds (android and ios) to be ready for distribution.

.

Code snippet from ChapterList class component
          
            render() {
              return (
                <FlatList
                    onContentSizeChange={() => {
                      if (this.state.indexToShow > -1) {
                        this.flatListRef.scrollToIndex({
                          index: this.state.indexToShow,
                        });
                      }
                    }}
                    data={this.state.itemsToFlatFist}
                    ref={(ref) => {
                      this.flatListRef = ref;
                    }}
                    renderItem={({ item, index }) => this.getItem(item, index)}
                    keyExtractor={(item, index) => index.toString()}
                    style={{flex: 1}}
                  />
              );
            }
          
            transformText = (text) => {
              if ("»,«".indexOf(text.slice(0, 1)) > -1) {
                return text.slice(0, 2).toUpperCase() + text.slice(1).toLowerCase();
              }
              return text.slice(0, 1).toUpperCase() + text.slice(1).toLowerCase();
            };
          
            parseText = (text, index = 0) => {
              let SUPPORTED_TAGS = this.getSupportedTags();
              let tags = Object.keys(SUPPORTED_TAGS);
              let tag = tags[index];
              let list = text.split(`<${tag}>`);
              if (list.length == 1) {
                return index < tags.length ? (
                  this.parseText(list[0], index + 1, true)
                ) : (
                  <Text key={index}>{list[0]}</Text>
                );
              } else {
                return list.map((item, i) => {
                  if (item.length > 0) {
                    let items = [];
          
                    if (item.indexOf(``) != -1) {
                      let split = item.split(``);
                      items.push(SUPPORTED_TAGS[tag](split[0], `${i}.1`));
                      items.push(
                        index < tags.length && split[1] ? (
                          this.parseText(split[1], index + 1, true)
                        ) : (
                          <Text key={i}>{split[1]}</Text>
                        )
                      );
                    } else {
                      items.push(this.parseText(item, index + 1, true));
                    }
          
                    return items;
                  }
                });
              }
            };
          
            updateContentWithSearchParams = (content, chapter) => {
              if (this.props.searchKeys && this.props.searchKeys.length) {
                let reg = new RegExp("<yellow>", "gi");
                content = content.replace(reg, "");
                reg = new RegExp("</yellow>", "gi");
                content = content.replace(reg, "");
          
                let count = 0;
                let newContent = content;
                this.props.searchKeys.map((key) => {
                  newContent.toLowerCase().indexOf(key.toLowerCase()) > -1 && count++;
                  reg = new RegExp(
                    `(${key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`,
                    "gi"
                  );
                  newContent = newContent.replace(reg, "<yellow>$1</yellow>");
                });
                if (count >= this.props.searchKeys.length) {
                  content = newContent;
                } else if (!this.checkInChapterHaveContent(chapter)) {
                  content = "";
                }
              }
              return content;
            };
          
            searchInBook = (book) => {
              let foundedSectionInBook = (word) => {
                let allSections = book.sections || [];
                let indexOfFoundSection = -1;
          
                allSections.forEach((section, index) => {
                  let havingWordInObject = this.searchWordInObject(section, word);
                  if (havingWordInObject && indexOfFoundSection == -1) {
                    indexOfFoundSection = index;
                  }
                });
          
                return indexOfFoundSection != -1;
              };
          
              let sectionIndex = false;
          
              if (this.props.searchKeys.length == 0) {
                return true;
              }
              this.props.searchKeys.forEach((selWord) => {
                sectionIndex = foundedSectionInBook(selWord);
              });
          
              return sectionIndex;
            };
          
            searchWordInObject = (theObject, searchWordInner) => {
              let result = false;
              if (theObject instanceof Array) {
                for (var i = 0; i < theObject.length; i++) {
                  result = this.searchWordInObject(theObject[i], searchWordInner);
                  if (result) {
                    break;
                  }
                }
              } else {
                for (var prop in theObject) {
                  if (prop == "content" || prop == "title") {
                    if (typeof theObject[prop] == "string") {
                      if (
                        theObject[prop]
                          .toLowerCase()
                          .indexOf(searchWordInner.toLowerCase()) > -1
                      ) {
                        return true;
                      }
                    }
                  } else if (prop == "ratio") {
                    let foundInColumns = false;
                    theObject.columns.forEach((colName) => {
                      if (
                        typeof colName == "string" &&
                        colName.toLowerCase().indexOf(searchWordInner) > -1 &&
                        !foundInColumns
                      ) {
                        foundInColumns = true;
                      }
                    });
                    let foundInRows = false;
                    if (!foundInColumns) {
                      theObject.rows.forEach((row) => {
                        row.forEach((word) => {
                          if (
                            typeof word == "string" &&
                            word.toLowerCase().indexOf(searchWordInner) > -1 &&
                            !foundInRows
                          ) {
                            foundInRows = true;
                          }
                        });
                      });
                    }
          
                    return foundInColumns || foundInRows;
                  }
                  if (
                    theObject[prop] instanceof Object ||
                    theObject[prop] instanceof Array
                  ) {
                    result = this.searchWordInObject(theObject[prop], searchWordInner);
                    if (result) {
                      break;
                    }
                  }
                }
              }
              return result;
            };
          
            getItem = (item, index) => {
              let onPress = () => {
                // console.log("item: ", item)
          
                if (item.isSubchapter) {
          
                  this.props.toggleChapter(item, index + 1, this.props.searchKeys);
                  return;
                }
                let newIndex = -1;
                if (this.state.indexToShow != index) {
                  newIndex = index;
                }
                newIndex = Math.min(newIndex, item.id - 1);
                this.setState({ indexToShow: newIndex }, () => {
                  let subchapters = [...BOOKS]
                    .filter(
                      (el) =>
                        el.chapterId == item.id && this.state.indexToShow == item.id - 1
                    )
                    .map((el) => ({ ...el, isSubchapter: true }));
          
                  let newFlatListData = [...this.state.itemsToFlatFist].filter(
                    (el) => !el.isSubchapter
                  );
                  newFlatListData.splice(item.id, 0, ...subchapters);
          
                  this.setState({
                    itemsToFlatFist: newFlatListData,
                  });
                });
              };
            
              ...
          
        

Back to projects