native platform prop

This commit is contained in:
Pete Matsyburka committed 2026-09-23 10:59:54 +03:00
1 parent 7e6331d1ad
commit 79f72c92b3
10 files changed
+36 -37

No files matched your search

+6 -1
View File
@@ -20,7 +20,8 @@ class ApplicationController < ActionController::Base
:true_ability, :true_ability,
:form_link_host, :form_link_host,
:svg_icon, :svg_icon,
:turbo_native_ios? :turbo_native_ios?,
:turbo_native_android?
impersonates :user, with: ->(uuid) { User.find_by(uuid:) } impersonates :user, with: ->(uuid) { User.find_by(uuid:) }
@@ -73,6 +74,10 @@ class ApplicationController < ActionController::Base
request.user_agent.to_s.include?('Hotwire Native iOS') request.user_agent.to_s.include?('Hotwire Native iOS')
end end
def turbo_native_android?
request.user_agent.to_s.include?('Hotwire Native Android')
end
def with_locale(&) def with_locale(&)
return yield unless current_account return yield unless current_account
+1 -2
View File
@@ -233,8 +233,7 @@ safeRegisterElement('template-builder', class extends HTMLElement {
currencies: (this.dataset.currencies || '').split(',').filter(Boolean), currencies: (this.dataset.currencies || '').split(',').filter(Boolean),
acceptFileTypes: this.dataset.acceptFileTypes, acceptFileTypes: this.dataset.acceptFileTypes,
showTourStartForm: this.dataset.showTourStartForm === 'true', showTourStartForm: this.dataset.showTourStartForm === 'true',
nativeApp: this.dataset.nativeApp === 'true', nativePlatform: this.dataset.nativePlatform
nativeIos: this.dataset.nativeIos === 'true'
}) })
this.component = this.app.mount(this.appElem) this.component = this.app.mount(this.appElem)
+14 -19
View File
@@ -78,7 +78,7 @@
v-if="$slots.buttons || withTitle" v-if="$slots.buttons || withTitle"
id="title_container" id="title_container"
class="flex justify-between py-1.5 items-center pr-4 top-0 z-10 title-container" class="flex justify-between py-1.5 items-center pr-4 top-0 z-10 title-container"
:class="{ sticky: withStickySubmitters || isBreakpointLg, hidden: nativeApp }" :class="{ sticky: withStickySubmitters || isBreakpointLg, hidden: !!nativePlatform }"
:style="{ backgroundColor }" :style="{ backgroundColor }"
> >
<div class="flex items-center space-x-3"> <div class="flex items-center space-x-3">
@@ -104,7 +104,7 @@
/> />
<template v-else> <template v-else>
<form-prompt <form-prompt
v-if="nativeApp && editable" v-if="!!nativePlatform && editable"
data-refresh="false" data-refresh="false"
> >
<native-action <native-action
@@ -140,7 +140,7 @@
</native-action> </native-action>
</form-prompt> </form-prompt>
<native-action <native-action
v-if="withSendButton && nativeApp" v-if="withSendButton && !!nativePlatform"
:data-label="t('send')" :data-label="t('send')"
data-icon="send" data-icon="send"
> >
@@ -156,8 +156,8 @@
data-icon="writing" data-icon="writing"
> >
<form <form
:target="nativeApp ? null : '_blank'" :target="!!nativePlatform ? null : '_blank'"
:data-turbo="nativeApp ? null : 'false'" :data-turbo="!!nativePlatform ? null : 'false'"
class="inline" class="inline"
method="post" method="post"
:action="`/start_form_self/${template.id}`" :action="`/start_form_self/${template.id}`"
@@ -211,7 +211,7 @@
</a> </a>
</native-action> </native-action>
<native-action <native-action
v-if="withSendButton && !nativeApp" v-if="withSendButton && !nativePlatform"
:data-label="t('send')" :data-label="t('send')"
data-icon="users_plus" data-icon="users_plus"
data-placement="bar" data-placement="bar"
@@ -219,7 +219,7 @@
<a <a
id="send_button" id="send_button"
:href="`/templates/${template.id}/submissions/new?with_link=true`" :href="`/templates/${template.id}/submissions/new?with_link=true`"
:data-turbo-frame="!nativeApp && isMobile && isBreakpointLg ? '_top' : 'modal'" :data-turbo-frame="!nativePlatform && isMobile && isBreakpointLg ? '_top' : 'modal'"
class="white-button md:!px-6" class="white-button md:!px-6"
@click="maybeShowErrorTemplateAlert" @click="maybeShowErrorTemplateAlert"
> >
@@ -309,7 +309,7 @@
> >
<a <a
:href="`/templates/${template.id}/preferences`" :href="`/templates/${template.id}/preferences`"
:data-turbo-frame="!nativeApp && isMobile && isBreakpointLg ? '_top' : 'modal'" :data-turbo-frame="!nativePlatform && isMobile && isBreakpointLg ? '_top' : 'modal'"
class="flex space-x-2" class="flex space-x-2"
@click="closeDropdown" @click="closeDropdown"
> >
@@ -324,7 +324,7 @@
data-icon="history" data-icon="history"
> >
<a <a
v-if="nativeApp" v-if="!!nativePlatform"
:href="`/templates/${template.id}/versions`" :href="`/templates/${template.id}/versions`"
data-turbo-frame="modal" data-turbo-frame="modal"
/> />
@@ -392,7 +392,7 @@
<div <div
id="main_container" id="main_container"
class="flex main-container" class="flex main-container"
:class="($slots.buttons || withTitle) && !nativeApp ? (isMobile ? 'max-h-[calc(100%_-_60px)]' : 'md:max-h-[calc(100%_-_60px)]') : (isMobile ? 'max-h-[100%]' : 'md:max-h-[100%]')" :class="($slots.buttons || withTitle) && !nativePlatform ? (isMobile ? 'max-h-[calc(100%_-_60px)]' : 'md:max-h-[calc(100%_-_60px)]') : (isMobile ? 'max-h-[100%]' : 'md:max-h-[100%]')"
> >
<div <div
v-if="withDocumentsList" v-if="withDocumentsList"
@@ -886,7 +886,7 @@ export default {
isPaypalConnected: this.isPaypalConnected, isPaypalConnected: this.isPaypalConnected,
withFormula: this.withFormula, withFormula: this.withFormula,
withConditions: this.withConditions, withConditions: this.withConditions,
nativeIos: this.nativeIos, nativePlatform: this.nativePlatform,
withCustomFields: this.withCustomFields, withCustomFields: this.withCustomFields,
isInlineSize: this.isInlineSize, isInlineSize: this.isInlineSize,
defaultDrawFieldType: this.defaultDrawFieldType, defaultDrawFieldType: this.defaultDrawFieldType,
@@ -1104,15 +1104,10 @@ export default {
required: false, required: false,
default: true default: true
}, },
nativeApp: { nativePlatform: {
type: Boolean, type: String,
required: false, required: false,
default: false default: ''
},
nativeIos: {
type: Boolean,
required: false,
default: false
}, },
withFieldsSearch: { withFieldsSearch: {
type: Boolean, type: Boolean,
@@ -515,7 +515,7 @@ export default {
ContextSubmenu, ContextSubmenu,
ContextModal ContextModal
}, },
inject: ['t', 'getFieldTypeIndex', 'template', 'withCustomFields', 'currencies', 'dateFormats', 'locale', 'withFormula', 'withConditions', 'nativeIos'], inject: ['t', 'getFieldTypeIndex', 'template', 'withCustomFields', 'currencies', 'dateFormats', 'locale', 'withFormula', 'withConditions', 'nativePlatform'],
props: { props: {
contextMenu: { contextMenu: {
type: Object, type: Object,
@@ -608,10 +608,10 @@ export default {
return !['stamp', 'heading', 'strikethrough'].includes(this.field.type) return !['stamp', 'heading', 'strikethrough'].includes(this.field.type)
}, },
showCondition () { showCondition () {
return this.withCondition && (this.withConditions || !this.nativeIos) && !['stamp', 'heading'].includes(this.field.type) return this.withCondition && (this.withConditions || this.nativePlatform !== 'ios') && !['stamp', 'heading'].includes(this.field.type)
}, },
showFormula () { showFormula () {
return (this.field.type === 'number' || this.field.type === 'payment' || !!this.field.preferences?.formula) && (this.withFormula || !this.nativeIos) return (this.field.type === 'number' || this.field.type === 'payment' || !!this.field.preferences?.formula) && (this.withFormula || this.nativePlatform !== 'ios')
}, },
showRequired () { showRequired () {
return this.withRequired && !['phone', 'stamp', 'verification', 'strikethrough', 'heading'].includes(this.field.type) return this.withRequired && !['phone', 'stamp', 'verification', 'strikethrough', 'heading'].includes(this.field.type)
@@ -484,7 +484,7 @@
</label> </label>
</li> </li>
<li <li
v-if="withCondition && (withConditions || !nativeIos) && field.type != 'stamp' && field.type != 'heading'" v-if="withCondition && (withConditions || nativePlatform !== 'ios') && field.type != 'stamp' && field.type != 'heading'"
class="field-settings-condition" class="field-settings-condition"
> >
<label <label
@@ -500,7 +500,7 @@
</label> </label>
</li> </li>
<li <li
v-if="(field.type == 'number' || field.preferences?.formula) && (withFormula || !nativeIos)" v-if="(field.type == 'number' || field.preferences?.formula) && (withFormula || nativePlatform !== 'ios')"
class="field-settings-formula" class="field-settings-formula"
> >
<label <label
@@ -610,7 +610,7 @@ export default {
IconTypography, IconTypography,
IconX IconX
}, },
inject: ['template', 't', 'dateFormats', 'locale', 'withFormula', 'withConditions', 'nativeIos'], inject: ['template', 't', 'dateFormats', 'locale', 'withFormula', 'withConditions', 'nativePlatform'],
props: { props: {
field: { field: {
type: Object, type: Object,
+2 -2
View File
@@ -271,7 +271,7 @@
</div> </div>
</button> </button>
<div <div
v-else-if="type == 'phone' && !nativeIos && (fieldTypes.length === 0 || fieldTypes.includes(type))" v-else-if="type == 'phone' && nativePlatform !== 'ios' && (fieldTypes.length === 0 || fieldTypes.includes(type))"
class="tooltip tooltip-bottom flex" class="tooltip tooltip-bottom flex"
:class="{'tooltip-bottom-end': withPayment, 'tooltip-bottom': !withPayment }" :class="{'tooltip-bottom-end': withPayment, 'tooltip-bottom': !withPayment }"
:data-tip="t('unlock_sms_verified_phone_number_field_with_paid_plan_use_text_field_for_phone_numbers_without_verification')" :data-tip="t('unlock_sms_verified_phone_number_field_with_paid_plan_use_text_field_for_phone_numbers_without_verification')"
@@ -422,7 +422,7 @@ export default {
IconBracketsContain, IconBracketsContain,
DynamicVariables: defineAsyncComponent(() => import(/* webpackChunkName: "dynamic-editor" */ './dynamic_variables')) DynamicVariables: defineAsyncComponent(() => import(/* webpackChunkName: "dynamic-editor" */ './dynamic_variables'))
}, },
inject: ['save', 'backgroundColor', 'withPhone', 'withVerification', 'withKba', 'withPayment', 'nativeIos', 't', 'fieldsDragFieldRef', 'customDragFieldRef', 'baseFetch', 'selectedAreasRef', 'getFieldTypeIndex'], inject: ['save', 'backgroundColor', 'withPhone', 'withVerification', 'withKba', 'withPayment', 'nativePlatform', 't', 'fieldsDragFieldRef', 'customDragFieldRef', 'baseFetch', 'selectedAreasRef', 'getFieldTypeIndex'],
props: { props: {
fields: { fields: {
type: Array, type: Array,
@@ -199,7 +199,7 @@
>{{ t('learn_more') }}</a> >{{ t('learn_more') }}</a>
</div> </div>
<li <li
v-if="withFormula || !nativeIos" v-if="withFormula || nativePlatform !== 'ios'"
class="field-settings-formula mb-1" class="field-settings-formula mb-1"
> >
<label <label
@@ -229,7 +229,7 @@
</label> </label>
</li> </li>
<li <li
v-if="withCondition && (withConditions || !nativeIos)" v-if="withCondition && (withConditions || nativePlatform !== 'ios')"
class="field-settings-condition mt-1" class="field-settings-condition mt-1"
> >
<label <label
@@ -287,7 +287,7 @@ export default {
IconBrandStripe, IconBrandStripe,
IconBrandPaypal IconBrandPaypal
}, },
inject: ['backgroundColor', 'save', 'currencies', 't', 'isStripeConnected', 'isPaypalConnected', 'withStripe', 'withPaypal', 'withFormula', 'withConditions', 'nativeIos'], inject: ['backgroundColor', 'save', 'currencies', 't', 'isStripeConnected', 'isPaypalConnected', 'withStripe', 'withPaypal', 'withFormula', 'withConditions', 'nativePlatform'],
props: { props: {
field: { field: {
type: Object, type: Object,
@@ -192,7 +192,7 @@ export default {
ConditionsModal, ConditionsModal,
ContextSubmenu ContextSubmenu
}, },
inject: ['t', 'save', 'selectedAreasRef', 'getFieldTypeIndex', 'withConditions', 'nativeIos'], inject: ['t', 'save', 'selectedAreasRef', 'getFieldTypeIndex', 'withConditions', 'nativePlatform'],
props: { props: {
contextMenu: { contextMenu: {
type: Object, type: Object,
@@ -259,7 +259,7 @@ export default {
return true return true
}, },
showCondition () { showCondition () {
return this.withCondition && (this.withConditions || !this.nativeIos) return this.withCondition && (this.withConditions || this.nativePlatform !== 'ios')
}, },
fieldNames: FieldType.computed.fieldNames, fieldNames: FieldType.computed.fieldNames,
fieldLabels: FieldType.computed.fieldLabels fieldLabels: FieldType.computed.fieldLabels
+1 -1
View File
@@ -10,4 +10,4 @@
<% account_configs = current_account.account_configs.where(key: [AccountConfig::TEMPLATE_CUSTOM_FIELDS_KEY, AccountConfig::TEMPLATE_DATE_FORMATS_KEY]).to_a %> <% account_configs = current_account.account_configs.where(key: [AccountConfig::TEMPLATE_CUSTOM_FIELDS_KEY, AccountConfig::TEMPLATE_DATE_FORMATS_KEY]).to_a %>
<% custom_fields = account_configs.find { |e| e.key == AccountConfig::TEMPLATE_CUSTOM_FIELDS_KEY }&.value || [] %> <% custom_fields = account_configs.find { |e| e.key == AccountConfig::TEMPLATE_CUSTOM_FIELDS_KEY }&.value || [] %>
<% date_formats = account_configs.find { |e| e.key == AccountConfig::TEMPLATE_DATE_FORMATS_KEY }&.value || [] %> <% date_formats = account_configs.find { |e| e.key == AccountConfig::TEMPLATE_DATE_FORMATS_KEY }&.value || [] %>
<template-builder data-native-app="<%= turbo_native_app? %>" data-native-ios="<%= turbo_native_ios? %>" class="grid" data-template="<%= @template_data.to_json %>" data-custom-fields="<%= custom_fields.to_json %>" data-date-formats="<%= date_formats.to_json %>" data-with-sign-yourself-button="<%= !@template.archived_at? %>" data-with-fields-detection="true" data-with-send-button="<%= !@template.archived_at? && can?(:create, @template.submissions.new(account: current_account)) %>" data-with-revisions-menu="<%= @template.template_versions.exists? %>" data-locale="<%= I18n.locale %>" data-show-tour-start-form="<%= @show_tour_start_form %>"></template-builder> <template-builder data-native-platform="<%= turbo_native_ios? ? 'ios' : (turbo_native_android? ? 'android' : '') %>" class="grid" data-template="<%= @template_data.to_json %>" data-custom-fields="<%= custom_fields.to_json %>" data-date-formats="<%= date_formats.to_json %>" data-with-sign-yourself-button="<%= !@template.archived_at? %>" data-with-fields-detection="true" data-with-send-button="<%= !@template.archived_at? && can?(:create, @template.submissions.new(account: current_account)) %>" data-with-revisions-menu="<%= @template.template_versions.exists? %>" data-locale="<%= I18n.locale %>" data-show-tour-start-form="<%= @show_tour_start_form %>"></template-builder>
+1 -1
View File
@@ -1,2 +1,2 @@
<% content_for(:native_title, @template.name) if turbo_native_app? %> <% content_for(:native_title, @template.name) if turbo_native_app? %>
<template-builder data-native-app="<%= turbo_native_app? %>" class="grid" data-editable="false" data-with-sign-yourself-button="<%= !@template.archived_at? %>" data-with-send-button="<%= !@template.archived_at? && can?(:create, @template.submissions.new(account: current_account)) %>" data-template="<%= @template_data.to_json %>"></template-builder> <template-builder data-native-platform="<%= turbo_native_ios? ? 'ios' : (turbo_native_android? ? 'android' : '') %>" class="grid" data-editable="false" data-with-sign-yourself-button="<%= !@template.archived_at? %>" data-with-send-button="<%= !@template.archived_at? && can?(:create, @template.submissions.new(account: current_account)) %>" data-template="<%= @template_data.to_json %>"></template-builder>