Google рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╕рдВрдЧреНрд░рд╣рдг рдХреЗ рд░реВрдк рдореЗрдВ рдбреНрд░рд╛рдЗрд╡ рдХрд░реЗрдВ

рдкреНрд░рд╕реНрддрд╛рд╡рдирд╛


рдореЗрд░рд╛ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди localStorage рдореЗрдВ рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░ рдХрд░ рд░рд╣рд╛ рд╣реИред рдпрд╣ рддрдм рддрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдерд╛ рдЬрдм рддрдХ рдореИрдВ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд┐рднрд┐рдиреНрди рдЙрдкрдХрд░рдгреЛрдВ рд╕реЗ рд╕рд╛рдЗрдЯ рддрдХ рдкрд╣реБрдВрдЪрддреЗ рд╕рдордп рдПрдХ рд╣реА рдЪреАрдЬ рдХреЛ рджреЗрдЦреЗред рдпрд╛рдиреА рд░рд┐рдореЛрдЯ рд╕реНрдЯреЛрд░реЗрдЬ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред

рд▓реЗрдХрд┐рди рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ GitHub рдкреЗрдЬ рдкрд░ "рд╣реЛрд╕реНрдЯ" рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рд╕рд░реНрд╡рд░ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдирд╣реАрдВ рд╣реИред рдореИрдВрдиреЗ рдПрдХ рд╕рд░реНрд╡рд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рд╕рд╛рде рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд▓рд╛рдн рджреЗрддрд╛ рд╣реИ:

  1. рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП рднреБрдЧрддрд╛рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдЗрд╕рдХреА рд╕реНрдерд┐рд░рддрд╛ рдФрд░ рдЙрдкрд▓рдмреНрдзрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рд┐рд░ рдХреЛ рдЪреЛрдЯ рдирд╣реАрдВ рдкрд╣реБрдВрдЪрд╛рддрд╛ рд╣реИред
  2. рдХрдо рдХреЛрдб, рдХрдо рддреНрд░реБрдЯрд┐рдпрд╛рдБред
  3. рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдореЗрд░реЗ рдЖрд╡реЗрджрди рдореЗрдВ рдкрдВрдЬреАрдХрд░рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ (рдпрд╣ рдмрд╣реБрддреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╖реНрдЯрдкреНрд░рдж рд╣реИ)ред
  4. рдЧреЛрдкрдиреАрдпрддрд╛ рдЕрдзрд┐рдХ рд╣реИ, рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдЙрд╕рдХрд╛ рдбреЗрдЯрд╛ рдПрдХ рдРрд╕реА рдЬрдЧрд╣ рдкрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рд╡рд╣ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдореБрдЭ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рддрд╛ рд╣реИред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╡рд┐рдХрд▓реНрдк RemoteStorage.js рдкрд░ рдЧрд┐рд░ рдЧрдпрд╛ред рд╡реЗ рдПрдХ рдУрдкрди рдбреЗрдЯрд╛ рдПрдХреНрд╕рдЪреЗрдВрдЬ рдкреНрд░реЛрдЯреЛрдХреЙрд▓, рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдПрдкреАрдЖрдИ, Google рдбреНрд░рд╛рдЗрд╡ рдФрд░ рдбреНрд░реЙрдкрдмреЙрдХреНрд╕ рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛, рд╕рд╛рде рд╣реА рд╕рд╛рде рдЕрдкрдиреЗ рд╕рд░реНрд╡рд░ рдХреА рдкреЗрд╢рдХрд╢ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рд░рд╛рд╕реНрддрд╛ рдПрдХ рдорд░рд╛ рд╣реБрдЖ рдЕрдВрдд рдмрди рдЧрдпрд╛ (рдХреНрдпреЛрдВ - рдПрдХ рдЕрд▓рдЧ рдХрд╣рд╛рдиреА)ред

рдЕрдВрдд рдореЗрдВ, рдореИрдВрдиреЗ рд╕реАрдзреЗ Google рдбрд┐рд╕реНрдХ рдФрд░ Google API рдХреНрд▓рд╛рдЗрдВрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА (рдЗрд╕рдХреЗ рдмрд╛рдж GAPI) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, Google рдкреНрд░рд▓реЗрдЦрди рдирд┐рд░рд╛рд╢рд╛рдЬрдирдХ рд╣реИ, рдФрд░ GAPI рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЕрдзреВрд░рд╛ рджрд┐рдЦрддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕рдХреЗ рдХрдИ рд╕рдВрд╕реНрдХрд░рдг рд╣реИрдВ, рдФрд░ рдпрд╣ рд╣рдореЗрд╢рд╛ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдХреМрди рд╕рд╛ рдкреНрд░рд╢реНрди рдореЗрдВ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдореЗрд░реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рдбреЙрдХреНрдпреВрдореЗрдВрдЯреЗрд╢рди, рд╕реНрдЯреИрдХрдСрд╡рд░рдлрд╝реНрд▓реЛ рдФрд░ рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рд░реИрдВрдбрдо рдкреЛрд╕реНрдЯреНрд╕ рдХреЗ рдкреНрд░рд╢реНрдиреЛрдВ рдФрд░ рдЙрддреНрддрд░реЛрдВ рд╕реЗ рдЯреБрдХрдбрд╝реЛрдВ рдореЗрдВ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдерд╛ред

рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдореЗрдВ Google рдбреНрд░рд╛рдЗрд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рдЖрд▓реЗрдЦ рдЖрдкрдХреЛ рд╕рдордп рдмрдЪрд╛рддрд╛ рд╣реИред

рдЯреНрд░реЗрдирд┐рдВрдЧ


Google API рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдХреБрдВрдЬреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИред рдпрджрд┐ рдЖрдк рд░реБрдЪрд┐ рдирд╣реАрдВ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рд╕реАрдзреЗ рдЕрдЧрд▓реЗ рднрд╛рдЧ рдкрд░ рдЬрд╛рдПрдВред

рдЪрд╛рдмреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛
Google рдбреЗрд╡рд▓рдкрд░ рдХрдВрд╕реЛрд▓ рдореЗрдВ, рдПрдХ рдирдпрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ , рдПрдХ рдирд╛рдо рджрд░реНрдЬ рдХрд░реЗрдВред

"рдХрдВрдЯреНрд░реЛрд▓ рдкреИрдирд▓" рдореЗрдВ "рд╕рдХреНрд╖рдо рдПрдкреАрдЖрдИ рдФрд░ рд╕реЗрд╡рд╛рдПрдВ" рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ рдФрд░ Google рдбреНрд░рд╛рдЗрд╡ рдЪрд╛рд▓реВ рдХрд░реЗрдВред

рдЗрд╕рдХреЗ рдмрд╛рдж, рдПрдкреАрдЖрдИ рдФрд░ рд╕реЗрд╡рд╛рдУрдВ -> рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓ рдЕрдиреБрднрд╛рдЧ рдкрд░ рдЬрд╛рдПрдВ, "рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓реНрд╕ рдмрдирд╛рдПрдВ" рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред рдЖрдкрдХреЛ рддреАрди рдХрд╛рдо рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ:

  1. "OAuth рдПрдХреНрд╕реЗрд╕ рдЕрдиреБрд░реЛрдз рд╡рд┐рдВрдбреЛ" рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВред рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдирд╛рдо, "рдЕрдзрд┐рдХреГрдд рдбреЛрдореЗрди" рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдЕрдкрдирд╛ рдбреЛрдореЗрди рдФрд░ рдЖрд╡реЗрджрди рдХреЗ рдореБрдЦреНрдп рдкреГрд╖реНрда рдХрд╛ рд▓рд┐рдВрдХ рджрд░реНрдЬ рдХрд░реЗрдВред рдЕрдиреНрдп рдХреНрд╖реЗрддреНрд░ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИрдВред
  2. "рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓" рдЕрдиреБрднрд╛рдЧ рдореЗрдВ, "рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓реНрд╕ рдмрдирд╛рдПрдВ" -> "OAuth рдХреНрд▓рд╛рдЗрдВрдЯ рдЖрдЗрдбреЗрдВрдЯрд┐рдлрд╝рд╛рдпрд░" рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред "рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди" рдХрд╛ рдЪрдпрди рдХрд░реЗрдВред рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рд╡рд┐рдВрдбреЛ рдореЗрдВ, "рд╕реНрд╡реАрдХреГрдд рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реНрд░реЛрдд" рдФрд░ "рдЕрдиреБрдордд рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ URI" рдЬреЛрдбрд╝реЗрдВред
    • рдЖрдкрдХрд╛ рдбреЛрдореЗрди (рдЖрд╡рд╢реНрдпрдХ)
    • http://localhost:8000 (рд╕реНрдерд╛рдиреАрдп рд╕реНрддрд░ рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡реИрдХрд▓реНрдкрд┐рдХ)ред


  3. "рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓" рдЕрдиреБрднрд╛рдЧ рдореЗрдВ, "рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓реНрд╕ рдмрдирд╛рдПрдВ" -> "рдПрдкреАрдЖрдИ рдХреБрдВрдЬреА" рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред рдореБрдЦреНрдп рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдореЗрдВ, рдкреНрд░рддрд┐рдмрдВрдз рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ:
    • рдЕрдиреБрдордд рдЖрд╡реЗрджрди рдкреНрд░рдХрд╛рд░ -> HTTP рд╕рдВрджрд░реНрдн (рд╡реЗрдмрд╕рд╛рдЗрдЯ)
    • рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд░реЗрдлрд╝рд░рд▓ рд╕реНрд░реЛрддреЛрдВ (рд╕рд╛рдЗрдЯреЛрдВ) -> рдЕрдкрдиреЗ рдбреЛрдореЗрди рдФрд░ рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ (рдмрд┐рдВрджреБ 2 рдореЗрдВ) рд╕реЗ http рдЕрдиреБрд░реЛрдз рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдВред
    • рдорд╛рдиреНрдп API -> Google рдбрд┐рд╕реНрдХ API



рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓ рдЕрдиреБрднрд╛рдЧ рдХреЛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:



рдпрд╣рд╛рдБ рд╣рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред рд╣рдо рдХреЛрдб рдХреЛ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред

рдЖрд░рдореНрдн рдФрд░ рд▓реЙрдЧрд┐рди


GAPI рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Google рдХрд╛ рдЕрдиреБрд╢рдВрд╕рд┐рдд рддрд░реАрдХрд╛ рдирд┐рдореНрди рдХреЛрдб рдХреЛ рдЕрдкрдиреЗ HTML рдореЗрдВ рдкреЗрд╕реНрдЯ рдХрд░рдирд╛ рд╣реИ:

 <script src="https://apis.google.com/js/api.js" onload="this.onload=function(){}; gapi.load('client:auth2', initClient)" onreadystatechange="if (this.readyState === 'complete') this.onload()"> </script> 

рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, initClient рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рд╕реНрд╡рдпрдВ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рдХреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрдкрд╕реНрдерд┐рддрд┐ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

 function initClient() { gapi.client.init({ //   API apiKey: GOOGLE_API_KEY, //    clientId: GOOGLE_CLIENT_ID, // ,     Google Drive API v3 discoveryDocs: ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest'], //    application data folder (. ) scope: 'https://www.googleapis.com/auth/drive.appfolder' }).then(() => { //    / (. ) gapi.auth2.getAuthInstance().isSignedIn.listen(onSignIn) //   initApp() }, error => { console.log('Failed to init GAPI client', error) //    initApp({showAlert: 'google-init-failed-alert'}) }) } 

рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░реЗрдЬ рдХреЗ рд▓рд┐рдП рд╣рдо рддрдерд╛рдХрдерд┐рдд рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреЗрдЯрд╛ рдлрд╝реЛрд▓реНрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдПрдХ рдирд┐рдпрдорд┐рдд рдлрд╝реЛрд▓реНрдбрд░ рдкрд░ рдЗрд╕рдХреЗ рдлрд╛рдпрджреЗ:

  1. рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрд╕реЗ рд╕реАрдзреЗ рдирд╣реАрдВ рджреЗрдЦрддрд╛ рд╣реИ: рдЗрд╕рдореЗрдВ рд╕реЗ рдлрд╝рд╛рдЗрд▓реЗрдВ рдЙрд╕рдХреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╕реНрдерд╛рди рдХреЛ рд░реЛрдХрддреА рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рд╡рд╣ рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛ рдХреЛ рдмрд░реНрдмрд╛рдж рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
  2. рдЕрдиреНрдп рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЗрд╕реЗ рдирд╣реАрдВ рджреЗрдЦрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдЦрд░рд╛рдм рднреА рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
  3. рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рд╕реНрдХреЛрдк, рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЗрд╕реЗ рдПрдХреНрд╕реЗрд╕ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рд╢реЗрд╖ рдлрд╝рд╛рдЗрд▓реЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рдпрд╣реА рд╣реИ, рд╣рдо рдХрд┐рд╕реА рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдЙрд╕рдХреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪ рдХреЗ рдЕрдиреБрд░реЛрдзреЛрдВ рд╕реЗ рдирд╣реАрдВ рдбрд░рд╛рдПрдВрдЧреЗред

Google API рдХреЗ рд╕рдлрд▓ рдЖрд░рдВрдн рд╣реЛрдиреЗ рдкрд░, рдлрд╝рдВрдХреНрд╢рди рдирд┐рдореНрди рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ:

  1. рд▓реЙрдЧрд┐рди / рд▓реЙрдЧрдЖрдЙрдЯ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ - рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ, рдпрд╣ рд╣рдореЗрд╢рд╛ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
  2. рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдкреНрд░рд╛рд░рдВрдн рдХрд░рддрд╛ рд╣реИред рдпрд╣ GAPI рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рдЖрд░рдВрдн рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдЬреИрд╕рд╛ рдЖрдк рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ Google рдЕрдиреБрдкрд▓рдмреНрдз рд╣реИ рддреЛ рдореЗрд░реА рдЖрд░рдВрднрд┐рдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдереЛрдбрд╝реА рднрд┐рдиреНрди рдереАред рдХреЛрдИ рдХрд╣ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ :) рд▓реЗрдХрд┐рди, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдк рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдХреБрдВрдЬреА рдФрд░ рдПрдХреНрд╕реЗрд╕ рдЕрдзрд┐рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рд╕реНрдорд╛рд░реНрдЯ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рджреВрд╕рд░реЗ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЪреАрди рдореЗрдВ, Google рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рд▓реЙрдЧрд┐рди рдФрд░ рд▓реЙрдЧрдЖрдЙрдЯ рдмрд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 function isGapiLoaded() { return gapi && gapi.auth2 } function logIn() { if (isGapiLoaded()) { //    Google    gapi.auth2.getAuthInstance().signIn() } } function logOut() { if (isGapiLoaded()) { gapi.auth2.getAuthInstance().signOut() } } 

рдЖрдк onSignIn рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рд▓реЙрдЧрд┐рди рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ:

 function isLoggedIn() { return isGapiLoaded() && gapi.auth2.getAuthInstance().isSignedIn.get() } function onSignIn() { if (isLoggedIn()) { //   } else { //   } //   .    "" } 

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЗрддрдирд╛ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИред

рд╣реЛрдирд╣рд╛рд░ рд╕рд╣рд╛рдпрдХ


GAPI рд╕рд╛рдорд╛рдиреНрдп рд╡рд╛рджреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдЗрд╕рдХрд╛ рдЕрдкрдирд╛ рдереЗрдирдмрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╡рд╛рджреЛрдВ рдХреЗ рд╕рдорд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдХрд╛рдлреА рдирд╣реАрдВред рдЗрд╕рд▓рд┐рдП, рдХрд╛рдо рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП (рдореБрдЦреНрдп рд░реВрдк рд╕реЗ async/await рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП), рд╣рдо рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╣рд╛рдпрдХ рдмрдирд╛рдПрдВрдЧреЗ:

 function prom(gapiCall, argObj) { return new Promise((resolve, reject) => { gapiCall(argObj).then(resp => { if (resp && (resp.status < 200 || resp.status > 299)) { console.log('GAPI call returned bad status', resp) reject(resp) } else { resolve(resp) } }, err => { console.log('GAPI call failed', err) reject(err) }) }) } 

рдпрд╣ рдлрд╝рдВрдХреНрд╢рди GAPI рд╡рд┐рдзрд┐ рдФрд░ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд╣рд▓реЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рд╡рд╛рджрд╛ рдХрд░рддрд╛ рд╣реИред рдлрд┐рд░ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░рдирд╛ рд╣реИред

рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ


рдЖрдкрдХреЛ рд╣рдореЗрд╢рд╛ рдпрд╛рдж рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ Google рдбреНрд░рд╛рдЗрд╡ рдкрд░ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рдЕрджреНрд╡рд┐рддреАрдп рдирд╣реАрдВ рд╣реИ ред рдЖрдк рдПрдХ рд╣реА рдирд╛рдо рд╕реЗ рдХрд┐рддрдиреА рднреА рдлрд╛рдЗрд▓реЗрдВ рдФрд░ рдлреЛрд▓реНрдбрд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдХреЗрд╡рд▓ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдЕрджреНрд╡рд┐рддреАрдп рд╣реИред
рдмреБрдирд┐рдпрд╛рджреА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдлрд╝реЛрд▓реНрдбрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд╕рднреА рдХрд╛рд░реНрдп рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреЗрдЯрд╛ рдлрд╝реЛрд▓реНрдбрд░ рдХреА рдЬрдбрд╝ рдореЗрдВ рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ рдЗрдВрдЧрд┐рдд рдХрд░рддреА рд╣реИрдВ рдХрд┐ рдлрд╝реЛрд▓реНрдбрд░реНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред Google рд╕реЗ рдкреНрд░рд▓реЗрдЦрди рдпрд╣рд╛рдБ рд╣реИ ред

рдПрдХ рдЦрд╛рд▓реА рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ


 async function createEmptyFile(name, mimeType) { const resp = await prom(gapi.client.drive.files.create, { resource: { name: name, //     // mimeType = 'application/vnd.google-apps.folder' mimeType: mimeType || 'text/plain', //  'appDataFolder'   ID  parents: ['appDataFolder'] }, fields: 'id' }) //    тАФ    return resp.result.id } 

рдпрд╣ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдЦрд╛рд▓реА рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ (рд╕реНрдЯреНрд░рд┐рдВрдЧ) рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдРрд╕реА рдХреЛрдИ рдлрд╝рд╛рдЗрд▓ рдкрд╣рд▓реЗ рд╕реЗ рдореМрдЬреВрдж рд╣реИ, рддреЛ рдЙрд╕реА рдирд╛рдо рд╡рд╛рд▓реА рдПрдХ рдирдИ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдИ рдЬрд╛рдПрдЧреА рдФрд░ рдЙрд╕рдХреА рдЖрдИрдбреА рд╡рд╛рдкрд╕ рдХрд░ рджреА рдЬрд╛рдПрдЧреАред рдпрджрд┐ рдЖрдк рдРрд╕рд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рдпрд╣ рджреЗрдЦрдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рд╕рдорд╛рди рдирд╛рдо рд╡рд╛рд▓реА рдХреЛрдИ рдлрд╝рд╛рдЗрд▓ рдирд╣реАрдВ рд╣реИ (рдиреАрдЪреЗ рджреЗрдЦреЗрдВ)ред
Google Drive рдПрдХ рдкреВрд░реНрдг рдбреЗрдЯрд╛рдмреЗрд╕ рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдХрдИ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдХ рд╣реА Google рдЦрд╛рддреЗ рд╕реЗ рд╡рд┐рднрд┐рдиреНрди рдЙрдкрдХрд░рдгреЛрдВ рд╕реЗ рдПрдХ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ, рддреЛ рд▓реЗрдирджреЗрди рдХреА рдХрдореА рдХреЗ рдХрд╛рд░рдг рд╕рдВрдШрд░реНрд╖реЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, Google рдбреНрд░рд╛рдЗрд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рди рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИред

рдлрд╝рд╛рдЗрд▓ рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ


рдЬреАрдПрдкреАрдЖрдИ (рдмреНрд░рд╛рдЙрдЬрд╝рд░-рдЖрдзрд╛рд░рд┐рдд рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП) рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ (рдмрд╣реБрдд рдЕрдЬреАрдм рд╣реИ, рд╣реИ рди!)ред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдПрдХ рд╕рд╛рдорд╛рдиреНрдп request рд╡рд┐рдзрд┐ рд╣реИ (рдПрдХ рд╕рд╛рдзрд╛рд░рдг AJAX рдЕрдиреБрд░реЛрдз рдкрд░ рдПрдХ рдкрддрд▓реА рдЖрд╡рд░рдг)ред

рдкрд░реАрдХреНрд╖рдг рдФрд░ рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдЖрдпрд╛:

 async function upload(fileId, content) { //    ,  ,     JSON return prom(gapi.client.request, { path: `/upload/drive/v3/files/${fileId}`, method: 'PATCH', params: {uploadType: 'media'}, body: typeof content === 'string' ? content : JSON.stringify(content) }) } async function download(fileId) { const resp = await prom(gapi.client.drive.files.get, { fileId: fileId, alt: 'media' }) // resp.body      // resp.result тАФ    resp.body  JSON. //   ,  resp.result  false // ..    ,   return resp.result || resp.body } 

рдлрд╝рд╛рдЗрд▓ рдЦреЛрдЬ


 async function find(query) { let ret = [] let token do { const resp = await prom(gapi.client.drive.files.list, { //  'appDataFolder'   ID  spaces: 'appDataFolder', fields: 'files(id, name), nextPageToken', pageSize: 100, pageToken: token, orderBy: 'createdTime', q: query }) ret = ret.concat(resp.result.files) token = resp.result.nextPageToken } while (token) // :    [{id: '...', name: '...'}], //     return ret } 

рдпрд╣ рдлрд╝рдВрдХреНрд╢рди, рдпрджрд┐ рдЖрдк query рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдлрд╝реЛрд▓реНрдбрд░ ( id рдФрд░ name рдлрд╝реАрд▓реНрдб рдХреЗ рд╕рд╛рде рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреА рдПрдХ рд╕рд░рдгреА) рдореЗрдВ рд╕рднреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рд╕реГрдЬрди рд╕рдордп рджреНрд╡рд╛рд░рд╛ рдХреНрд░рдордмрджреНрдзред

рдпрджрд┐ рдЖрдк query рд╕реНрдЯреНрд░рд┐рдВрдЧ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ (рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдпрд╣рд╛рдБ рд╡рд░реНрдгрд┐рдд рд╣реИ ), рддреЛ рдпрд╣ рдХреНрд╡реЗрд░реА рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рд╡рд╛рд▓реА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд▓реМрдЯрд╛ рджреЗрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЬрд╛рдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ config.json рдирд╛рдордХ рдлрд╝рд╛рдЗрд▓ config.json , рдЖрдкрдХреЛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ

  if ((await find('name = "config.json"')).length > 0) { // ()  } 

рдлрд╝рд╛рдЗрд▓реЗрдВ рд╣рдЯрд╛рдирд╛


 async function deleteFile(fileId) { try { await prom(gapi.client.drive.files.delete, { fileId: fileId }) return true } catch (err) { if (err.status === 404) { return false } throw err } } 

рдпрд╣ рдлрд╝рдВрдХреНрд╢рди ID рджреНрд╡рд╛рд░рд╛ рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╣рдЯрд╛ рджреЗрддрд╛ true рдФрд░ рдпрджрд┐ рд╡рд╣ рдРрд╕реА рдХреЛрдИ рдлрд╝рд╛рдЗрд▓ рдирд╣реАрдВ рдереА, рддреЛ рдпрд╣ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдбрд┐рд▓реАрдЯ рд╣реЛ рдЬрд╛рддреА рд╣реИ, рдФрд░ false ред

рддреБрд▓реНрдпрдХрд╛рд▓рди


рдпрд╣ рд╕рд▓рд╛рд╣ рджреА рдЬрд╛рддреА рд╣реИ рдХрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореБрдЦреНрдп рд░реВрдк рд╕реЗ localStorage рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ Google рдбреНрд░рд╛рдЗрд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ localStorage рдбреЗрдЯрд╛ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдХ рд╕рд░рд▓ рд╡рд┐рдиреНрдпрд╛рд╕ рддреБрд▓реНрдпрдХрд╛рд▓рди рд░рдгрдиреАрддрд┐ рд╣реИ:

  1. рдирдпрд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдПрдХ рд▓реЙрдЧрд┐рди рдХреЗ рд╕рд╛рде Google рдбреНрд░рд╛рдЗрд╡ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рд╣рд░ 3 рдорд┐рдирдЯ рдореЗрдВ, рд╕реНрдерд╛рдиреАрдп рдХреЙрдкреА рдХреЛ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рдХрд░рддрд╛ рд╣реИ;
  2. рд╕реНрдерд╛рдиреАрдп рдкрд░рд┐рд╡рд░реНрддрди Google рдбреНрд░рд╛рдЗрд╡ рдкрд░ рдбрд╛рд▓реЗ рдЧрдП рд╣реИрдВ, рдЬреЛ рд╡рд╣рд╛рдБ рдерд╛, рдЙрд╕ рдкрд░ рдУрд╡рд░рд░рд╛рдЗрдЯрд┐рдВрдЧ;
  3. рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди fileID рдХреЛ рдХрд╛рдо рдореЗрдВ рддреЗрдЬреА рд▓рд╛рдиреЗ рдФрд░ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП fileID рдореЗрдВ рдХреИрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ;
  4. рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ (рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ) рд╕реНрдерд┐рддрд┐ рддрдм рд╣реЛрддреА рд╣реИ рдЬрдм Google рдбреНрд░рд╛рдЗрд╡ рдореЗрдВ рдХрдИ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЗрдВ рд╣реЛрддреА рд╣реИрдВ, рдФрд░ рдЬрдм рдХрд┐рд╕реА рдиреЗ рд╣рдорд╛рд░реА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдпрд╛ рдЗрд╕реЗ рдмрд░реНрдмрд╛рдж рдХрд░ рджрд┐рдпрд╛ред
  5. рд╕рд┐рдВрдХ рд╡рд┐рд╡рд░рдг рдмрд╛рдХреА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛрдб рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдХреЗрд╡рд▓ рджреЛ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ: getConfig() рдФрд░ saveConfig(newConfig) ред

рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ, рдЖрдк рд╕рдВрднрд╡рдд: рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рд▓реЛрдб / рдЕрдирд▓реЛрдб рдХрд░рддреЗ рд╕рдордп рдЕрдзрд┐рдХ рд▓рдЪреАрд▓реЗ рд╕рдВрдШрд░реНрд╖ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдХреЛрдб рджреЗрдЦреЗрдВ
 //     const SYNC_PERIOD = 1000 * 60 * 3 // 3  //    const DEFAULT_CONFIG = { // ... } //  ID  ,      let configSyncTimeoutId async function getConfigFileId() { //  configFileId let configFileId = localStorage.getItem('configFileId') if (!configFileId) { //     Google Drive const configFiles = await find('name = "config.json"') if (configFiles.length > 0) { //   (  )  configFileId = configFiles[0].id } else { //   configFileId = await createEmptyFile('config.json') } //  ID localStorage.setItem('configFileId', configFileId) } return configFileId } async function onSignIn() { //   / (. ) if (isLoggedIn()) { //   //  (  -?)    scheduleConfigSync(0) } else { //   //          //   config file ID localStorage.removeItem('configFileId') //  localStorage   ,    } } function getConfig() { let ret try { ret = JSON.parse(localStorage.getItem('config')) } catch(e) {} //    ,    return ret || {...DEFAULT_CONFIG} } async function saveConfig(newConfig) { //    ,     localStorage.setItem('config', JSON.stringify(newConfig)) if (isLoggedIn()) { //  config file ID const configFileId = await getConfigFileId() //     Google Drive upload(configFileId, newConfig) } } async function syncConfig() { if (!isLoggedIn()) { return } //  config file ID const configFileId = await getConfigFileId() try { //   const remoteConfig = await download(configFileId) if (!remoteConfig || typeof remoteConfig !== 'object') { //    ,   upload(configFileId, getConfig()) } else { //  ,    localStorage.setItem('config', JSON.stringify(remoteConfig)) } //  ,  localStorage   } catch(e) { if (e.status === 404) { // -   ,   fileID     localStorage.removeItem('configFileId') syncConfig() } else { throw e } } } function scheduleConfigSync(delay) { //   ,    if (configSyncTimeoutId) { clearTimeout(configSyncTimeoutId) } configSyncTimeoutId = setTimeout(() => { //      syncConfig() .catch(e => console.log('Failed to synchronize config', e)) .finally(() => scheduleSourcesSync()) }, typeof delay === 'undefined' ? SYNC_PERIOD : delay) } function initApp() { //      scheduleConfigSync() } 


рдирд┐рд╖реНрдХрд░реНрд╖


рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ Google рдбреНрд░рд╛рдЗрд╡ рдкрд░ рдПрдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░ рдЫреЛрдЯреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдФрд░ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИред рдпрд╣ рди рдХреЗрд╡рд▓ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдФрд░ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИ, рдмрд▓реНрдХрд┐ рдмреНрд░рд╣реНрдорд╛рдВрдб рдореЗрдВ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдореЗрдВ рднреА рдорджрдж рдХрд░рддрд╛ рд╣реИред рдФрд░ рдореЗрд░рд╛ рд▓реЗрдЦ, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ, рдпрджрд┐ рдЖрдк рдЗрд╕ рдкрде рдХреЛ рдЪреБрдирдиреЗ рдореЗрдВ рд╕рдордп рдмрдЪрд╛рдиреЗ рдореЗрдВ рдЖрдкрдХреА рдорджрдж рдХрд░реЗрдВрдЧреЗред

PS рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдХреЛрдб GitHub рдкрд░ рд╣реИ , рдЖрдк рдЗрд╕реЗ рдпрд╣рд╛рдБ рдЖрдЬрд╝рдорд╛ рд╕рдХрддреЗ рд╣реИрдВ ред

Source: https://habr.com/ru/post/hi440844/


All Articles