[Electron] 16.최근 검색어 저장 - 레시피 일렉트론 앱

최근 검색어 목록1

 

 

최근 검색어 목록2

GitHub

https://github.com/bsorryman/recipe-bag

 

개요

메인 화면 및 검색 결과 화면 내의 검색창에서 최근 검색어를 저장하는 기능을 추가한다.

 

JavaScript 코드

    
    req_loadRecentKeywords: () => ipcRenderer.send("req_loadRecentKeywords"),
    resp_loadRecentKeywords: (keywordList) => ipcRenderer.on('resp_loadRecentKeywords', keywordList),
    req_pushRecentKeyword: (keyword) => ipcRenderer.send("req_pushRecentKeyword", keyword),
    req_delRecentKeyword: (index) => ipcRenderer.send("req_delRecentKeyword", index)

preload.js

 

Renderer 단에서 사용할 최근 검색어를 불러오고, 저장하며, 삭제하는 송신/수신 채널을 선언한다.

 

  addLoadRecentKewords() {
    ipcMain.on('req_loadRecentKeywords', (event) => {
      let keywordList = this.recentKeyword.loadRecentKeywords();
      this.mainWindow.webContents.postMessage('resp_loadRecentKeywords', keywordList);
    });
  }    

  addPushRecentKeyword() {
    ipcMain.on('req_pushRecentKeyword', (event, keyword) => {
      keyword = this.recentKeyword.pushRecentKeyword(keyword);
    });    
  }

  addDelRecentKeyword() {
    ipcMain.on('req_delRecentKeyword', (event, index) => {
      this.recentKeyword.deleteRecentKeyword(index);
    })
  }

rcp_ipc.js

 

Renderer 측의 최근 검색어 조회, 저장, 삭제 요청을 처리할 ipc 리스너를 등록한다. 저장, 삭제는 따로 결과를 return 하지 않고, 조회하는 loadRecentKeywords 채널만 조회 결과를 반환한다.

 

const { app, BrowserWindow } = require('electron');
const fs = require('fs');
const path = require('path');

export default class RecentKeyword {
    recentKeywordsFilePath;
    recentKeywords;

    constructor(){
        this.recentKeywordsFilePath = path.join(app.getPath('userData'), 'recentKeywords.json');
        this.recentKeywords = this.loadRecentKeywords();
    }

    loadRecentKeywords() {
        try {
            return JSON.parse(fs.readFileSync(this.recentKeywordsFilePath));
        } catch (error) {
            return [];
        }
    }

    saveRecentKeywords() {
        const maxRecentKeywords = 50;

        if (this.recentKeywords.length > maxRecentKeywords) {
            this.recentKeywords.pop();
        }     

        fs.writeFileSync(this.recentKeywordsFilePath, JSON.stringify(this.recentKeywords));
    }    

    pushRecentKeyword(keyword) {
        this.recentKeywords.unshift(keyword);
        this.saveRecentKeywords();        
    }

    deleteRecentKeyword(index) {
        if (index >= 0 && index < this.recentKeywords.length) {
            const deletedKeyword = this.recentKeywords.splice(index, 1)[0];
            this.saveRecentKeywords();
        }
    }
}

rcp_recent_keyword.js

 

최근 검색어를 조회, 저장, 삭제할 수 있는 클래스를 만들었다. 인스턴스 생성 시에 app.getPath('userData') 를 통해서, 최근 검색어 파일 recenyKeywords.json을 저장할 곳으로 해당 앱의 정보를 담는 경로를 지정하고 불러온다. (최초 호출 시 경로 내 json 파일 생성)

 

loadRecentKeywords()

- 현재 앱 데이터 내에 저장된 최근 검색어 파일의 JSON 데이터를 파싱하여 반환한다. 

 

saveRecentKeywords()

- 현재 인스턴스에 설정된 최근 검색어 배열을 파일 경로에 JSON으로 저장한다. 단, 최대 저장 개수는 50으로 넘어간다면 맨 마지막 검색어를 삭제한다. 

 

pushRecentKeyword(keyword)

- 검색어를 최근 검색어 배열에 넣고 저장한다. 

 

deleteRecentKeyword(index)

- 최근 검색어 배열에서 해당 index의 검색어를 삭제하고 저장한다.

 

/**
 * A function that requests search results from all columns.
 * @param {*} keyword 
 * @param {*} pageNum 
 */
function requestSearch(keyword, column, pageNum) {
  gPageNum = pageNum;
  window.apis.req_searchRcpList(keyword, column, pageNum); // A search request to the main process.
  if (gAllRecipe != 'y') {
    window.apis.req_pushRecentKeyword(gKeyword);
  }
  window.apis.req_loadRecentKeywords();
}

.
.
.

window.apis.resp_loadRecentKeywords((event, keywordList)=>{
  let historyBox = $('.history_box');
  historyBox.empty();

  let keyworListHtml = '';
  let index = 0;

  if (keywordList.length == 0) {
    gNoHisotry = true;
    $('.history_box').hide();

    return;
  } else {
    gNoHisotry = false;
  }

  $.each(keywordList, (key, value) => {
    keyworListHtml +=
    `
    <li class="history_list">
      <p class="history_tit">${value}</p>
      <button type="button" class="close_btn" id="del${index}"><span class="txt_hidden">Icon Delete</span></button>
    </li>
    `
    index++;
  });

  historyBox.append(keyworListHtml);
  setKeywordButton();
  setCloseButton();
});

function setCloseButton() {
  let idList = $('.close_btn');
  $.each(idList, (key, value) => {
    value.onclick = () => {
      let index = value.id.substring(3, value.id.length);
      window.apis.req_delRecentKeyword(index);
      window.apis.req_loadRecentKeywords();
    }
  });
}

function setKeywordButton() {
  let idList = $('.history_list');
  $.each(idList, (key, value) => {
    value.onclick = (event) => {
      if (!$(event.target).hasClass('close_btn')) { 
        let keyword = $(value).find('.history_tit').text();
        $('#keyword').val(keyword);
      }
    }
  });  
}

search_result > renderer.js

 

검색 시에 검색어를 최근 검색어 목록에 저장하고, 검색창 클릭 시 최근 검색어 목록을 드랍다운 방식으로 조회한다. 또한 목록에서 x 버튼을 클릭하면 최근 검색어를 삭제한다. 

 

requestSearch(keyword, column, pageNum)

- 검색을 요청할 때, ipc 통신을 통해 main 단으로 검색어 저장을 요청한다. (pushRecenyKeyword)

 

window.apis.resp_loadRecneyKeywords((event, keywordList) -> { ... })

- 최근 검색어 조회 요청의 응답을 받아, 검색창 밑에 표시되는 최근 검색어 목록을 갱신하고, 각 검색어의 삭제 버튼 클릭 이벤트 리스너를 등록한다.

 

setCloseButton()

- 최근 검색어 목록의 삭제 버튼 클릭 시 해당 index의 검색어를 삭제하고, 최근 검색어 목록을 갱신한다.

 

setKeywordButton()

- 검색어 클릭 시 검색창에 입력하도록 한다.