Slide 1

Slide 1 text

ElectronʹΑΔΞϓϦ έʔγϣϯ։ൃࣄ৘ 2018 builderscon tokyo 2018 @h3_poteto

Slide 2

Slide 2 text

ࣗݾ঺հ • Akira Fukushimaʢ෱ౡ ໌ʣ • github: h3poteto • twitter: h3_poteto • Mastodon: @[email protected] • ࢓ࣄɿterraform৬ਓ@scouty

Slide 3

Slide 3 text

એ఻

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

σεΫτοϓ޲͚ͷ MastodonΫϥΠΞϯτΛ ࡞͍ͬͯ·͢

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

ࠓ೔͸͜ͷΞϓϦέʔγϣ ϯΛ୊ࡐʹElectronͷ࿩Λ ͠·͢

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

એ఻ऴΘΓ

Slide 10

Slide 10 text

ࠓ೔ͷ࿩ • ElectronͰΞϓϦέʔγϣϯ࡞ΔͷϚδͰָ ͩΑʢͲΜͲΜָʹͳΓͭͭ͋Δ • Ͱ΋SNSͷΫϥΠΞϯτ࡞Δͷ͸େม • ւ֎੎͔Βͷҙ֎ͳ൓Ԡ͋ͬͨ • ΈΜͳMastodon΍ͬͯ΄͍͠

Slide 11

Slide 11 text

ElectronͰΞϓϦέʔγϣϯ Λ։ൃ͢Δ

Slide 12

Slide 12 text

Electron? • ੲ͸Atom-shellͱݺ͹Ε͍ͯͨ • Chromium + Node.js • Windows/Mac/Linux޲͚ͷΞϓϦέʔγϣϯ ͕࡞ΕΔ

Slide 13

Slide 13 text

ͭ·Γ • දࣔ෦෼͸ϒϥ΢βͳͷͰWebϑϩϯτΤϯ υͷٕज़Λ࢖͑Δ • React.js/Vue.js΋ࡌͤΒΕΔ • SPAͰΞϓϦ͕࡞ΕΔ

Slide 14

Slide 14 text

vue-cliͰ਽ܗ͕࡞ΕΔ $ npm install -g vue-cli $ vue init simulatedgreg/electron-vue \ whalebird

Slide 15

Slide 15 text

vue-cliͰͷ਽ܗ • webpackʹΑΔ։ൃ࣌ͷϏϧυઃఆ • auto-reload • ςετͷ਽ܗ

Slide 16

Slide 16 text

Electronͷجຊߏ଄ • mainϓϩηε: όοΫάϥ΢ϯυδϣϒɼΞϓ Ϧέʔγϣϯͷ؅ཧΛߦ͏ • rendererϓϩηε: jsΛ࣮ߦ͠html, cssΛϨϯ μϦϯά͢Δ

Slide 17

Slide 17 text

rendererϓϩηεଆΛ͢΂ͯ SPAʹ͢Δ͜ͱ͕Մೳ ͜͜ͰReact.js/Vue.js͕࢖͑ Δ

Slide 18

Slide 18 text

خ͍͜͠ͱᶃ React.js/Vue.js(Flux)ΛGUI ΞϓϦέʔγϣϯͰ࢖͑Δ

Slide 19

Slide 19 text

iOS։ൃ͍ͯͨ͜͠Ζ • ViewController͕ແݶʹଠΔʂ • delegate͕ͦ͜Βதʹ…… • ϞσϧͲ͏͜͏ͱ͍͏ΑΓঢ়ଶ΍ը໘ભҠͷ ϩδοΫ͕େม

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

class SwipeViewController: UIViewController, SwipeViewDelegate, SwipeViewDataSource, UINavigationControllerDelegate, UITabBarControllerDelegate { func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { if (type(of: viewController) === SwipeViewController.self) { for i in 0 ..< self.streamList.count() { self.viewItems[i].fCellSelect = false } } } } ͛͢ʔ͍ͬͺ͍Delegateͯ͠Δ

Slide 22

Slide 22 text

React.js/Vue.sj(Flux)ʹ͢Δͱ • ࠩ෼ϨϯμϦϯά͸React.js/Vue.jsͷ૚͕΍ͬ ͯ͘ΕΔ͜ͱ͕લఏ • delegateͱ͔ඞཁͳ͍ • Flux͕σʔλͷྲྀΕΛҰํ޲ʹͯ͘͠ΕΔ • GUIΞϓϦέʔγϣϯͳͷʹݟ௨͕͠ྑ͍

Slide 23

Slide 23 text

focusToot (message) { this.focusedId = message.uri }

Slide 24

Slide 24 text

خ͍͜͠ͱᶄ ίϯτϦϏϡʔλ͕૿͑Δ

Slide 25

Slide 25 text

WhalebirdͷίϯτϦϏϡʔλ • ΄΅jsͷٕज़ͳͷͰjsք۾ͷਓ͕ίϯτϦ Ϗϡʔτ͠΍͍͢ʢ͜͜ͷϘϦϡʔϜ͕ଟ͍

Slide 26

Slide 26 text

خ͍͜͠ͱᶅ ΫϩεϓϥοτϑΥʔϜ

Slide 27

Slide 27 text

ΫϩεϓϥοτϑΥʔϜ • Windows/Mac/LinuxͰಉ͡ιʔεͷ··Ϗϧ υՄೳ • ͨͩ͠Ұ෦Mac޲͚ͷػೳ౳΋࣮૷͞Ε͍ͯ Δ

Slide 28

Slide 28 text

ྫ: Dockϝχϡʔ ϝχϡʔ಺༰͕ ΧελϚΠζՄೳ elecron-context-menu

Slide 29

Slide 29 text

خ͍͜͠ͱᶆ ΞΫςΟϒʹ։ൃ͞Ε͍ͯΔ

Slide 30

Slide 30 text

ElectronͷϦϦʔε͸ׂͱ׆ൃ • v2.0.8 - 2018/08/23 • v2.0.7 - 2018/08/09 • v2.0.6 - 2018/08/01 3.0.0४උத: v3.0.0-beta.8

Slide 31

Slide 31 text

ΞϓϦέʔγϣϯΛύοέʔ δϯάˍϦϦʔε

Slide 32

Slide 32 text

Let’s ElectronΈ͍ͨͳهࣄ͸ ͍ͬͺ͍͋Δ͚ͲϦϦʔεʹ ؔ͢Δهࣄ͕΄ͱΜͲͳ͍

Slide 33

Slide 33 text

֮͑ͯ΄͍͜͠ͱ: electron-builder͕͋Ε͹ͩ ͍͍ͨղܾ͢Δ

Slide 34

Slide 34 text

• electron-packager • electron-builder ͱ͍͏ͷ͕͋Δ

Slide 35

Slide 35 text

electron-packager • webpackͰίϯύΠϧ͞ΕͨϑΝΠϧ܈ΛΞ ϓϦέʔγϣϯͱͯ͠·ͱΊΔ • جຊతʹ͜Ε͔͠΍ͬͯ͘Εͳ͍ • ίϚϯυϥΠϯ

Slide 36

Slide 36 text

electron-builder • ΞϓϦέʔγϣϯͷύοέʔδϯά • ূ໌ॻͷ௥Ճ • ֤छΠϯετʔϧՄೳͳϑΝΠϧܗࣜʹѹॖ ʢ.dmg, .deb, .rpm, .exe౳ʣ • package.jsonʹઃఆ͕ॻ͚Δ • ެࣜυΩϡϝϯτ͕๛෋: 
 https://www.electron.build/

Slide 37

Slide 37 text

"build": { "productName": "Whalebird", "appId": "org.whalebird.desktop", "directories": { "output": "build" }, "mac": { "icon": "build/icons/icon.icns", "target": [ "dmg" ], "category": "public.app-category.social-networking" },

Slide 38

Slide 38 text

͓͔͛ͰϦϦʔεܗ͕ࣜ๛෋ • AppStore(.pkg) • .dmg • .exe • .deb • .rpm • .tar.bz2 • snapcraft (.snap)

Slide 39

Slide 39 text

ͪΐͬͱಛघͳઃఆྫ • ΞΠίϯ • ֎෦ϦιʔεʢԻ੠౳ʣ • ূ໌ॻ • MASʢMac App Storeʣ

Slide 40

Slide 40 text

ΞΠίϯ • Mac/Windows: Ϗϧυ࣌ʹຒΊࠐΉ • Linux: Ұ෦͸main.jsͰ֎෦ϑΝΠϧΛࢦఆ • ը૾ϑΝΠϧ͸asarѹॖ͞Ε͍ͯͯ΋಺෦ͷ΋ ͷΛࢦఆՄೳ

Slide 41

Slide 41 text

"build": { "productName": “Whalebird", "files": [ "dist/electron/**/*", "build/icons/*" ], "mac": { "icon": "build/icons/icon.icns", "target": [ "dmg" ], "category": "public.app-category.social-networking" }, "win": { "icon": "build/icons/icon.ico", "target": "nsis" }, iconͷࢦఆ

Slide 42

Slide 42 text

mainWindow = new BrowserWindow({ titleBarStyle: 'hidden', useContentSize: true, icon: path.resolve(__dirname, '../../build/icons/256x256.png') } BrowserWindowͷ ىಈΦϓγϣϯͰΞΠίϯΛࢦఆ

Slide 43

Slide 43 text

֎෦ϦιʔεͷಡΈࠐΈ • Ի੠ϑΝΠϧ౳ΛಡΈࠐΈ͍ͨ৔߹͕͋Δ • asarѹॖ಺ͷϑΝΠϧ͸ಡΈऔΕͳ͍ • ϏϧυઃఆͰasarѹॖ͔Βআ֎͢Δඞཁ͕͋ Δ

Slide 44

Slide 44 text

"build": { "productName": "Whalebird", "appId": "org.whalebird.desktop", "directories": { "output": "build" }, "extraResources": [ "build/sounds/*" ], "files": [ "dist/electron/**/*", "build/icons/*" ], Ի੠ΛextraResources ʹࢦఆ

Slide 45

Slide 45 text

const soundBasePath = process.env.NODE_ENV === 'development' ? path.join(__dirname, '../../build/sounds/') : path.join(process.resourcesPath, 'build/sounds/') const sound = path.join(soundBasePath, 'operation_sound01.wav') simplayer(sound, (err) => { if (err) log.error(err) }) ͜͜͸asar֎ͷϑΝΠϧΛ ࢦఆ͢Δඞཁ͕͋Δ

Slide 46

Slide 46 text

Mac༻ͷূ໌ॻ • Developer ID Installer • Developer ID Application electron-builderͳΒϏϧυ࣌ʹ KeyChainAccess಺ͷূ໌ॻΛ ࣗಈͰ౰ͯͯ͘ΕΔ

Slide 47

Slide 47 text

MAS͚ͩ͸ಛผѻ͍ • electron-builderͰCodeSign·ͰͰ͖ͳ͔ͬͨ • electron-packagerͰϏϧυޙɼࣗ෼ͰCodeSign • plistΛࣗ෼Ͱॻ͘ඞཁ͕͋Δ • ͦΕΛApplication LoaderͰΞοϓϩʔυ͢Δ • ͋ͱ͸iTunes ConnectͰόʔδϣϯΞοϓ

Slide 48

Slide 48 text

#!/bin/zsh -f # Name of your app. APP="Whalebird" # The path of your app to sign. APP_PATH="./packages/Whalebird-mas-x64/Whalebird.app" # The path to the location you want to put the signed package. RESULT_PATH="./packages/$APP.pkg" # The name of certificates you requested. APP_KEY="3rd Party Mac Developer Application: Akira Fukushima (HB4N6B2YVM)" INSTALLER_KEY="3rd Party Mac Developer Installer: Akira Fukushima (HB4N6B2YVM)" # The path of your plist files. CHILD_PLIST="./plist/child.plist" PARENT_PLIST="./plist/parent.plist" LOGINHELPER_PLIST="./plist/loginhelper.plist" FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" # At first, rename app.asar.unpacked directory. # Because electron-builder does not store app.asar.unpacked directory. # I want to store unpacked files at the same directory as electron-builder. mv $APP_PATH/Contents/Resources/app.asar.unpacked/* $APP_PATH/Contents/Resources/ codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Electron Framework" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Libraries/libffmpeg.dylib" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Libraries/libnode.dylib" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/Contents/MacOS/$APP Helper EH" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/" codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper" codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP" codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH" productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH"

Slide 49

Slide 49 text

#!/bin/zsh -f # Name of your app. APP="Whalebird" # The path of your app to sign. APP_PATH="./packages/Whalebird-mas-x64/Whalebird.app" # The path to the location you want to put the signed package. RESULT_PATH="./packages/$APP.pkg" # The name of certificates you requested. APP_KEY="3rd Party Mac Developer Application: Akira Fukushima (HB4N6B2YVM)" INSTALLER_KEY="3rd Party Mac Developer Installer: Akira Fukushima (HB4N6B2YVM)" # The path of your plist files. CHILD_PLIST="./plist/child.plist" PARENT_PLIST="./plist/parent.plist" LOGINHELPER_PLIST="./plist/loginhelper.plist" FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" # At first, rename app.asar.unpacked directory. # Because electron-builder does not store app.asar.unpacked directory. # I want to store unpacked files at the same directory as electron-builder. mv $APP_PATH/Contents/Resources/app.asar.unpacked/* $APP_PATH/Contents/Resources/ codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Electron Framework" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Libraries/libffmpeg.dylib" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Libraries/libnode.dylib" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/Contents/MacOS/$APP Helper EH" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/" codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper" codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP" codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH" productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" codesignίϚϯυΛ࢖͑͹ྑ͍

Slide 50

Slide 50 text

com.apple.security.app-sandbox com.apple.security.application-groups HB4N6B2YVM.org.whalebird.desktop com.apple.security.files.user-selected.read-only com.apple.security.network.client

Slide 51

Slide 51 text

com.apple.security.app-sandbox com.apple.security.application-groups HB4N6B2YVM.org.whalebird.desktop com.apple.security.files.user-selected.read-only com.apple.security.network.client ͜͜Ͱ • ωοτϫʔΫΞΫηε • ϑΝΠϧΞΫηε ౳ΛڐՄ͢Δ

Slide 52

Slide 52 text

͜ͷ͋ͱ৹͕ࠪ͋Δʂ

Slide 53

Slide 53 text

MAS͸݁ߏͭΒ͍

Slide 54

Slide 54 text

͜͜·Ͱͷ·ͱΊ • electron-builderϚδ΂ΜΓ • electron-builderͷਐา͕଎͍ͷͰ͜Ε࢖ͬͱ ͚͹ؒҧ͍ͳ͍ • MAS͸͍ͭ΋େม

Slide 55

Slide 55 text

MastodonͷΫϥΠΞϯτΛ ࡞Δ

Slide 56

Slide 56 text

ͳͥMastodonͷ ΫϥΠΞϯτΛ࡞Δͷ͔

Slide 57

Slide 57 text

σεΫτοϓ޲͚ͷ ΫϥΠΞϯτ͕ͳ͍ɼຊ౰ʹগͳ͍ • Mstdnʢࣗ෼ͰjsonϑΝΠϧΛ༻ҙͯ͠token ΛೖΕΔʣ • The Desk • TsuruʢόΠφϦͷ഑෍͸ͳ͍ʣ

Slide 58

Slide 58 text

ͳ͍ͷͰ͋Ε͹ ࣗ෼Ͱͭ͘Ζ͏

Slide 59

Slide 59 text

Whalebirdͷίϯηϓτ • LinuxͰ࢖͑Δ΋ͷΛ • Slackʹ׳Ε͍ͯΔͷͰSlackΆ͍ݟͨ໨ • γϣʔτΧοτ͸ͱʹ͔͘ଟ͘ ࠷ڧͷTwitterΫϥΠΞϯτ ઓ૪Λࢥ͍ग़͢

Slide 60

Slide 60 text

ॳ൛͕Ͱ͖ͨ

Slide 61

Slide 61 text

ւ֎͔Βͷ൓Ԡ

Slide 62

Slide 62 text

ʢӳޠαϙʔτ͔ͨ͠Β͔ʣ ࠷ॳ͸ւ֎͔Β൓Ԡ͕

Slide 63

Slide 63 text

ϦϦʔεͯ͠࠷ॳͷҰिؒ

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

ྑ͍ʂ͚ͩͲElectron͔…… Έ͍ͨͳ൓Ԡ͹͔Γ

Slide 69

Slide 69 text

ͦΜͳʹElectronͬͯධ൑ѱ ͍ͷʁ ೔ຊͰ͸͋·Γฉ͔ͳ͔͚ͬͨͬͲ

Slide 70

Slide 70 text

ධ൑ͷѱ͞ • ϝϞϦফඅ͕ଟ͍ • SlackΛىಈ͢Δ͚ͩͰ500MBҎ্ϝϞϦΛ͍͔࣋ͬͯ ΕΔ • ࠷దԽ͞Εͯͳ͍ͷͰϝϞϦফඅ͕ଟ͍ • Javaͷํ͕͍ܰ • node.js͕ݏ͍

Slide 71

Slide 71 text

ϝϞϦͱઓ͏

Slide 72

Slide 72 text

࠷੝ظ͸1GBҎ্ ͍͔࣋ͬͯΕͨ

Slide 73

Slide 73 text

Ͳ͜ͰϝϞϦΛ ফඅ͍ͯ͠Δͷ͔ʁ

Slide 74

Slide 74 text

ࢼͯ͠ΈΔ • StreamingΛࢭΊͨঢ়ଶͰ͍Ζ͍Ζ৮ͬͯΈΔ • StreamingΛࢭΊͨঢ়ଶͰ์ஔ ϝϞϦϦʔΫ͔ʁ

Slide 75

Slide 75 text

StreamingࢭΊ͍ͯΔͱ૿͑ ͳ͍ʂ ผʹϝϞϦϦʔΫ͍ͯ͠ΔΘ ͚Ͱ͸ͳ͍ʂ

Slide 76

Slide 76 text

StreamingʹΑΔϝϞϦফඅ • ຊ਺Λ૿΍ͯ͠ΈΔʁ

Slide 77

Slide 77 text

StreamingʹΑΔϝϞϦফඅ • όοΫάϥ΢ϯυͰStreaming͢Δ͚ͩͰ͸ର ͯ͠ϝϞϦΛফඅ͠ͳ͍ʂ

Slide 78

Slide 78 text

΋͏গ͠ࢼ͢ • ྲྀ଎ͷ஗͍ΠϯελϯεͰ์ஔʢmikutterʣ • ྲྀ଎ͷ଎͍ΠϯελϯεͰ์ஔʢjpʣ

Slide 79

Slide 79 text

໌Β͔ʹྲྀ଎͕଎͍΄͏͕ ϝϞϦফඅ͕ଟ͍

Slide 80

Slide 80 text

͜Ε͸΋͠΍ϨϯμϦϯά ͳͷͰ͸ʁ

Slide 81

Slide 81 text

WhalebirdͷλΠϜϥΠϯඳը • Streaming͞Εͨ΋ͷΛ͢΂ͯhtmlͱͯ͠දࣔ ͍ͯͨ͠ • ͭ·Γ͸ϒϥ΢βͷ࣮૷ʹؙ౤͛ • FireFoxͰ΋ڊେϖʔδΛ։͍ͨΒॏ͍
 ʢ͔ͩΒΈΜͳϖʔδωʔγϣϯ͢ΔΜͩ

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

ଞ͸Ͳ͏͍ͯ͠Δͷ͔ʁ

Slide 84

Slide 84 text

iOSͷ৔߹ • UITableView͸දࣔ͞Ε͍ͯΔ෦෼͔͠Ϩϯμ Ϧϯά͍ͯ͠ͳ͍ • ӅΕ͍ͯΔ෼·ͰؚΊͨεΫϩʔϧྔ͸ܭࢉ ͍ͯ͠Δ • εΫϩʔϧ͞Εͨࡍ͸දࣔ͢Δ௚લʹ಺༰Λ ౎౓ϨϯμϦϯά

Slide 85

Slide 85 text

Slide 86

Slide 86 text

දࣔ͞Ε͍ͯͳ͍෦෼͸ ϨϯμϦϯά͍ͯ͠ͳ͍

Slide 87

Slide 87 text

UITableViewController • cellForRowAt: ηϧͷத਎ΛϨϯμϦϯά • heightForRowAt: ηϧͷߴ͞Λࢉग़ • estimatedHeightForRowAt: ະදࣔ෼ΛؚΊͯ ηϧͷߴ͞Λࢉग़

Slide 88

Slide 88 text

ྲྀੴʹ͜Ε͸ύΫΕͳ͍

Slide 89

Slide 89 text

ϙΠϯτɿ ඳը͢Δൣғ͸ݟ͍͑ͯΔ ෦෼͘Β͍Ͱे෼

Slide 90

Slide 90 text

ElectronͰͲ͏͢Δ͔ʁ • λΠϜϥΠϯΛ͢΂ͯදࣔ͢ΔͷΛ΍ΊΔ • ࠷৽40݅ͷΈΛදࣔ͠ɼඞཁͰ͋Ε͹ LazyLoading • StreamingͰߋ৽͞Εͨ৔߹͸ɼݹ͍΋ͷΛফ ͯ͠40݅ʹอͭ

Slide 91

Slide 91 text

No content

Slide 92

Slide 92 text

εΫϩʔϧΠϕϯτΛ΋ͱʹ੍ޚͯ͠΍Δ

Slide 93

Slide 93 text

200MBΛ੾Δʂ

Slide 94

Slide 94 text

ѹ౗త͡Όͳ͍͔ʂ

Slide 95

Slide 95 text

ϙΠϯτɿ Vue.jsͷύϑΥʔϚϯεʹ΋ ؾΛ഑Δ

Slide 96

Slide 96 text

vue.jsͷύϑΥʔϚϯε • v-ifͱv-show • v-if: ੾ସ࣌ʹhtml͕ੜ੒͞ΕϨϯμϦϯά͞ ΕΔ • v-show: ͸͡Ί͔ΒϨϯμϦϯά͞Εͯ͸͍Δ ͕ɼdisplay: none͞Ε͍ͯΔ͚ͩ

Slide 97

Slide 97 text

v-ifͱv-show • v-ifͷ੾ସ࣌ϨϯμϦϯάίετ͸അࣛʹͳΒ ͳ͍ • ͔͠͠ɼඞཁͷͳ͍ͱ͜ΖΛv-showʹ͢Δͱ ͣͬͱϝϞϦΛফඅ͠ଓ͚Δ

Slide 98

Slide 98 text

͜͜͸ਖ਼ղ͕ͳ͍

Slide 99

Slide 99 text

࠷ۙͷWhalebird • ϝϞϦফඅ: 200MB ~ 500MB • 500MB͘Β͍·Ͱ͘ΔͱGC͞ΕͯϝϞϦফඅ ͕ҰؾʹݮΔ • ը૾͕গͳ͍࣌ؒଳ͸͍ܰʂ
 ʢpawooͷਓ͝ΊΜͳ͍͞

Slide 100

Slide 100 text

࠷ۙͷWhalebird • ϕʔεʹͳ͍ͬͯΔElectronΛόʔδϣϯΞο ϓ͢ΔͱϝϞϦফඅ͕ݮΔ • ύϑΥʔϚϯε͸Chromiumʹ߹ΘͤͯͲΜͲ Μྑ͘ͳΔ

Slide 101

Slide 101 text

͜ͷઌͷ࡞ઓ • ը૾ͷඇදࣔΦϓγϣϯ • τΡʔτ͕࿈ଓ͢Δ৔߹͸·ͱΊͯϨϯμϦ ϯάͰ͖ͳ͍͔ʁ

Slide 102

Slide 102 text

͓ӄ༷Ͱ࠷ۙͷ൓Ԡ͸ྑ͍

Slide 103

Slide 103 text

APIΫϥΠΞϯτϥΠϒϥϦ Λࣗ࡞͢Δ

Slide 104

Slide 104 text

౰ॳ͸mastodon-apiͱ͍͏ Node.jsͷϥΠϒϥϦΛར༻

Slide 105

Slide 105 text

͕ɼΤϥʔʹͳΔͱ͍͏ใࠂ ͕ͪΒ΄Β

Slide 106

Slide 106 text

mastodon-api • POSTύϥϝʔλΛbodyͰ͸ͳ͘urlύϥϝʔ λͱͯ͠ૹ৴͍ͯ͠Δ • Ұ෦αʔόͰ͸ͦΕΒ͕ڋ൱͞Ε͍ͯΔ ଞͷબ୒ࢶ͕ͳ͍

Slide 107

Slide 107 text

ͳ͍ͷͳΒࣗ࡞͠Α͏

Slide 108

Slide 108 text

No content

Slide 109

Slide 109 text

megalodon • TypeScriptͰॻ͍ͨmastodonAPIΫϥΠΞϯ τϥΠϒϥϦ • Streaming΋࣮૷ࡁΈ • OAuthΞϓϦέʔγϣϯొ࿥༻ϝιου΋༻ ҙ

Slide 110

Slide 110 text

public get(path: string, params = {}): Promise> { return axios .get(this.baseUrl + path, { headers: { 'Authorization': `Bearer ${this.accessToken}` }, params }) .then((resp: AxiosResponse) => { const res: Response = { data: resp.data, status: resp.status, statusText: resp.statusText, headers: resp.headers } return res }) }

Slide 111

Slide 111 text

όάͬͯͨ৔߹͸ શ෦ࣗ෼Ͱ࣏ͤΔ

Slide 112

Slide 112 text

ΠϯελϯεΛ ݐͯΔ͜ͱ΋͋Δ

Slide 113

Slide 113 text

ΠϯελϯεݪҼͷ໰͍߹Θͤ ͸ଟ͍ • ϩάΠϯ͕Ͱ͖ͳ͍ • τΡʔτͰ͖ͳ͍ • Streaming͕ಈ͔ͳ͍ • ౳ʑ……

Slide 114

Slide 114 text

࠷ۙ͋ͬͨ൵͍͠ࣄྫ • (mastodon͕࢖͍ͬͯΔ)doorkeeper 4.3.0Ҏ ্ Ͱnative_redirect_uriʹؔ͢Δόά͕ࠞೖ • mastodon: doorkeeper ~> 4.4.1 • σεΫτοϓΞϓϦέʔγϣϯͰೝূ͕Ͱ͖ ͳ͘ͳΔ

Slide 115

Slide 115 text

͔֬ΊΔ&ϓϧϦΫΛग़͢ • खݩͰmastodonαʔόΛݐͯΔ: 
 https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/ Development-guide.md • ࠶ݱͨ͠ • doorkeeperʹissueཱͯͨΓɼmastodonʹϓ ϧϦΫΛૹͬͨΓ

Slide 116

Slide 116 text

No content

Slide 117

Slide 117 text

ΫϥΠΞϯτ͚ͩͷ໰୊Ͱ͸ͳ͍͜ͱ͕ଟ͍ͷͰɼ αΫοͱΠϯελϯεΛཱͯΒΕΔΑ͏ʹ ͓ͯ͘͠ͷॏཁ

Slide 118

Slide 118 text

·ͱΊ

Slide 119

Slide 119 text

੒ޭͨ͠ͳʔͱࢥ͏͜ͱ • ElectronͰ࡞ͬͨ͜ͱ • Vue.jsͱ͍͏બ୒ • ӳޠݍ΁ͷ഑ྀ

Slide 120

Slide 120 text

ࣦഊͨ͠ͳʔͱࢥ͏͜ͱ • ΋ͬͱૣ͘࡞Ε͹Α͔ͬͨ • ΋ͬͱૣ͘TypeScriptΛߟྀ͢΂͖ͩͬͨ • megalodon(APIΫϥΠΞϯτ)͸ϝϯς͠΍ ͍͢ • ద౰ͳΦϒδΣΫτΛ౉͢͜ͱ͕ଟ͍

Slide 121

Slide 121 text

updateTimeFormat ({ dispatch, commit, state }, value) { const newGeneral = Object.assign({}, state.general, { timeFormat: value }) const config = { general: newGeneral } ipcRenderer.send('update-preferences', config) ipcRenderer.once('error-update-preferences', (event, err) => { ipcRenderer.removeAllListeners('response-update-preferences') }) ipcRenderer.once('response-update-preferences', (event, conf) => { ipcRenderer.removeAllListeners('error-update-preferences') dispatch('App/loadPreferences', null, { root: true }) commit('updateGeneral', conf.general) }) }, action͸ͻͱ͔ͭ͠Ҿ਺ΛऔΕͳ͍ mainͱͷ௨৴͸ipcͰߦ͏ ະ஌ͷΦϒδΣΫτ

Slide 122

Slide 122 text

શମతʹݟͯ • Electron͸ʢϦϦʔεํ๏΋ؚΊͯʣਐԽͯ͠ ͍ΔͷͰ͓͢͢Ί͍ͨ͠ • ϝϞϦফඅ͸ରࡦՄೳ • Vue.jsͰGUIΞϓϦέʔγϣϯ։ൃ͢Δͷ͸ྑ ͍

Slide 123

Slide 123 text

Mastodon͕ շదʹͳͬͨͷͰ TwitterΛݟΔ͜ͱ͕ݮͬͨ

Slide 124

Slide 124 text

͞Α͏ͳΒTwitter ΫϥΠΞϯτ