require 'uri' # GUIまわり class App Document = JSrb.document def self.images @images ||= {} end def self.card_thumbnail=(file) @card_thumbnail = file end def self.card_thumbnail @card_thumbnail end def self.setup self.new.setup end def setup @auth_button = Document.get_element_by_id('auth_button') @handle_area = Document.get_element_by_id('handle_area') @handle = Document.get_element_by_id('handle') @password = Document.get_element_by_id('password') @logout_button = Document.get_element_by_id('logout_button') @image_input = Document.get_element_by_id('image_input') @auth_area = Document.get_element_by_id('auth_area') @logout_area = Document.get_element_by_id('logout_area') @main = Document.get_element_by_id('main') @text = Document.get_element_by_id('text') @preview_area = Document.get_element_by_id('preview_area') @card_area = Document.get_element_by_id('card-area') @card_url = Document.get_element_by_id('card-url') @card_button = Document.get_element_by_id('card-button') @card_title = Document.get_element_by_id('card-title') @card_desc = Document.get_element_by_id('card-desc') @card_thumb = Document.get_element_by_id('card-thumb') @card_preview_area = Document.get_element_by_id('card-preview-area') @post_button = Document.get_element_by_id('post') @cancel_button = Document.get_element_by_id('cancel') begin handle = Bsky.new.session['handle'] @handle_area.inner_text = handle hide_auth_area rescue Bsky::NoSession show_auth_area end @auth_button.add_event_listener('click') { begin session = Bsky.create_session(@handle.value, @password.value) @handle_area.inner_text = session['handle'] hide_auth_area rescue => e JSrb.global.alert(e.message) raise e end } @logout_button.add_event_listener('click') { Bsky.destroy_session show_auth_area } @image_input.add_event_listener('change') { add_image } @card_button.add_event_listener('click') { begin meta = JSON.parse(Http.get("https://app.tmtms.net/cgi-bin/card-info.cgi?uri=#{URI.encode_www_form_component(@card_url.value)}").text.await.to_s) @card_title.value = meta['title'] @card_desc.value = meta['description'] @card_preview_area.inner_text = '' App.card_thumbnail = nil if meta['thumbnail'] div = render_image(meta['thumbnail']) { App.card_thumbnail = nil } img = div.query_selector('img') type = meta['thumbnail'].match(/data:(.*?);base64/)[1] canvas = Document.create_element('canvas') canvas.width = img.natural_width canvas.height = img.natural_height canvas.get_context('2d').draw_image(img, 0, 0) canvas.style = 'display: none' @card_preview_area.append_child(canvas) canvas.to_blob(->(b){ App.card_thumbnail = JSrb.new(b) @card_preview_area.append_child(div) }, type) end rescue => e p e end } @card_thumb.add_event_listener('change') { add_thumbnail } @post_button.add_event_listener('click') { unless @card_url.value.empty? card = { uri: @card_url.value, title: @card_title.value, description: @card_desc.value, thumbnail: App.card_thumbnail, } end begin Bsky.new.post(@text.value, images: App.images, card:) clear rescue => e JS.global.alert(e.message) end } @cancel_button.add_event_listener('click') { clear } end def clear @text.value = '' @preview_area.inner_text = '' @card_url.value = '' @card_title.value = '' @card_desc.value = '' @card_preview_area.inner_text = '' App.images.clear App.card_thumbnail = nil end def show_auth_area @auth_area.style.display = 'block' @logout_area.style.display = 'none' @main.style.display = 'none' end def hide_auth_area @auth_area.style.display = 'none' @logout_area.style.display = 'block' @main.style.display = 'block' end def add_image @image_input.files.each {|file| if file.size > 1000_000 JSrb.global.alert "#{file.name}: file size exceeded (#{file.size})" next end if file.type !~ /\Aimage\// JSrb.global.alert "#{file.name}: file is not image (#{file.type})" next end App.images[file.object_id] = file div = render_image(JSrb.global[:URL].createObjectURL(file)) { App.images.delete(file.object_id) } @preview_area.append_child(div) } @image_input.value = '' @image_input.value = '' end def render_image(src, &removed) div = Document.create_element('div') img = Document.create_element('img') button = Document.create_element('button') button.append_child(Document.create_text_node('削除')) button.add_event_listener('click') { removed&.call div.remove } img.src = src img.width = '400' div.append_child(img) div.append_child(button) div end def add_thumbnail file, = @card_thumb.files.to_a if file.size > 1000_000 JSrb.global.alert "#{file.name}: file size exceeded (#{file.size})" return end if file.type !~ /\Aimage\// JSrb.global.alert "#{file.name}: file is not image (#{file.type})" return end App.card_thumbnail = file div = render_image(JSrb.global[:URL].createObjectURL(file)) { App.card_thumbnail = nil } @card_preview_area.append_child(div) @card_thumb.value = '' end end