This commit is contained in:
Felix
2026-01-23 16:26:34 +08:00
parent 107283a69a
commit 4607db2721
2 changed files with 237 additions and 233 deletions

View File

@@ -24,253 +24,255 @@
<view class="process-dot {{processDotClasses[index]}} {{index === currentIndex ? 'current' : ''}}"></view>
</block>
</view>
<scroll-view class="question-scroll {{questionMode === 'conversation' && conversationViewMode === 'chat' && isChatInputVisible ? 'chat-input-mode-scroll' : 'chat-mode-scroll'}}" scroll-y="true" scroll-into-view="{{scrollIntoView}}" scroll-with-animation>
<view class="image-card" wx:if="{{questionMode !== 'variation'}}">
<image wx:if="{{imageLocalUrl}}" class="image" src="{{imageLocalUrl}}" mode="aspectFill" bindtap="previewImage" bindload="onImageLoad" binderror="onImageError"></image>
<view class="view-full" wx:if="{{imageLocalUrl}}" bindtap="previewImage">
<t-icon name="zoom-in" size="32rpx" />
<!-- <text>View Full</text> -->
</view>
</view>
<view class="question-title" wx:if="{{questionMode !== 'conversation'}}">
<text wx:for="{{questionWords}}" wx:key="index" class="word-item" data-word="{{item}}" bindtap="handleWordClick">{{item}}</text>
</view>
<view class="question-content {{modeAnim}}" wx:if="{{questionMode === 'choice'}}">
<view class="choice-title">Select the correct answer ({{selectedCount}}/{{choiceRequiredCount}})</view>
<view class="option-list">
<view wx:for="{{choiceOptions}}" wx:key="index" class="option-item {{evalClasses[index]}} {{(!choiceSubmitted && !selectedFlags[index] && selectedCount >= choiceRequiredCount) ? 'disabled' : ''}} {{resultDisplayed ? 'disabled' : ''}}" data-index="{{index}}" data-word="{{item.content}}" bindtap="selectOption" bindlongpress="onOptionLongPress">
<view class="option-radio">
<view class="radio-dot {{selectedFlags[index] ? 'on' : ''}} {{(evalClasses[index] === 'opt-incorrect' && selectedFlags[index]) ? 'red' : ''}}"></view>
</view>
<text class="option-text">{{item.content}}</text>
<view class="question-scroll-wrapper {{questionMode === 'conversation' && conversationViewMode === 'chat' && isChatInputVisible ? 'chat-input-mode-scroll' : 'chat-mode-scroll'}}">
<scroll-view class="inner-scroll" scroll-y="true" scroll-into-view="{{scrollIntoView}}" scroll-with-animation>
<view class="image-card" wx:if="{{questionMode !== 'variation'}}">
<image wx:if="{{imageLocalUrl}}" class="image" src="{{imageLocalUrl}}" mode="aspectFill" bindtap="previewImage" bindload="onImageLoad" binderror="onImageError"></image>
<view class="view-full" wx:if="{{imageLocalUrl}}" bindtap="previewImage">
<t-icon name="zoom-in" size="32rpx" />
<!-- <text>View Full</text> -->
</view>
</view>
</view>
<view class="question-content {{modeAnim}}" wx:if="{{questionMode === 'cloze'}}">
<!-- <view class="choice-title">Select the correct word to complete the sentence:</view> -->
<view class="cloze-sentence">
<text wx:for="{{clozeSentenceTokens}}" wx:key="index" class="{{item.isBlank ? 'cloze-fill' : 'cloze-text'}}" data-word="{{item.word}}" bindtap="handleWordClick">{{item.text}}</text>
<view class="question-title" wx:if="{{questionMode !== 'conversation'}}">
<text wx:for="{{questionWords}}" wx:key="index" class="word-item" data-word="{{item}}" bindtap="handleWordClick">{{item}}</text>
</view>
<view class="option-list">
<view wx:for="{{clozeOptions}}" wx:key="index" class="option-item {{evalClasses[index]}} {{resultDisplayed ? 'disabled' : ''}}" data-index="{{index}}" data-word="{{item}}" bindtap="selectClozeOption" bindlongpress="onOptionLongPress">
<view class="option-radio">
<view class="radio-dot {{selectedClozeIndex === index ? 'on' : ''}} {{(evalClasses[index] === 'opt-incorrect' && selectedClozeIndex === index) ? 'red' : ''}}"></view>
<view class="question-content {{modeAnim}}" wx:if="{{questionMode === 'choice'}}">
<view class="choice-title">Select the correct answer ({{selectedCount}}/{{choiceRequiredCount}})</view>
<view class="option-list">
<view wx:for="{{choiceOptions}}" wx:key="index" class="option-item {{evalClasses[index]}} {{(!choiceSubmitted && !selectedFlags[index] && selectedCount >= choiceRequiredCount) ? 'disabled' : ''}} {{resultDisplayed ? 'disabled' : ''}}" data-index="{{index}}" data-word="{{item.content}}" bindtap="selectOption" bindlongpress="onOptionLongPress">
<view class="option-radio">
<view class="radio-dot {{selectedFlags[index] ? 'on' : ''}} {{(evalClasses[index] === 'opt-incorrect' && selectedFlags[index]) ? 'red' : ''}}"></view>
</view>
<text class="option-text">{{item.content}}</text>
</view>
<text class="option-text">{{item}}</text>
</view>
</view>
</view>
<view class="question-content {{modeAnim}}" wx:if="{{questionMode === 'variation'}}">
<view class="variation-container">
<view class="variation-grid">
<view class="variation-item" wx:for="{{variationQaList}}" wx:key="index">
<view class="variation-image-wrapper {{index === variationSelectedIndex ? 'selected' : ''}}" data-index="{{index}}" bindtap="selectVariationOption">
<cloud-image
file-id="{{item.file_id}}"
mode="widthFix"
height="auto"
radius="24rpx"
bind:load="onVariationImageLoad"
data-fileid="{{item.file_id}}"
/>
<view class="view-full" wx:if="{{variationImageLoaded[item.file_id]}}" data-fileid="{{item.file_id}}" catchtap="previewVariationImage">
<t-icon name="zoom-in" size="32rpx" />
<view class="question-content {{modeAnim}}" wx:if="{{questionMode === 'cloze'}}">
<!-- <view class="choice-title">Select the correct word to complete the sentence:</view> -->
<view class="cloze-sentence">
<text wx:for="{{clozeSentenceTokens}}" wx:key="index" class="{{item.isBlank ? 'cloze-fill' : 'cloze-text'}}" data-word="{{item.word}}" bindtap="handleWordClick">{{item.text}}</text>
</view>
<view class="option-list">
<view wx:for="{{clozeOptions}}" wx:key="index" class="option-item {{evalClasses[index]}} {{resultDisplayed ? 'disabled' : ''}}" data-index="{{index}}" data-word="{{item}}" bindtap="selectClozeOption" bindlongpress="onOptionLongPress">
<view class="option-radio">
<view class="radio-dot {{selectedClozeIndex === index ? 'on' : ''}} {{(evalClasses[index] === 'opt-incorrect' && selectedClozeIndex === index) ? 'red' : ''}}"></view>
</view>
<text class="option-text">{{item}}</text>
</view>
</view>
</view>
<view class="question-content {{modeAnim}}" wx:if="{{questionMode === 'variation'}}">
<view class="variation-container">
<view class="variation-grid">
<view class="variation-item" wx:for="{{variationQaList}}" wx:key="index">
<view class="variation-image-wrapper {{index === variationSelectedIndex ? 'selected' : ''}}" data-index="{{index}}" bindtap="selectVariationOption">
<cloud-image
file-id="{{item.file_id}}"
mode="widthFix"
height="auto"
radius="24rpx"
bind:load="onVariationImageLoad"
data-fileid="{{item.file_id}}"
/>
<view class="view-full" wx:if="{{variationImageLoaded[item.file_id]}}" data-fileid="{{item.file_id}}" catchtap="previewVariationImage">
<t-icon name="zoom-in" size="32rpx" />
</view>
<view wx:if="{{variationImageLoaded[item.file_id]}}" class="selection-badge {{variationResultStatus === 'incorrect' && index === variationSelectedIndex ? 'incorrect' : (index === variationSelectedIndex ? 'selected' : 'unselected')}}">
<t-icon name="{{variationResultStatus === 'incorrect' && index === variationSelectedIndex ? 'close-circle' : 'check-circle'}}" size="36rpx" color="#fff" />
</view>
<view wx:if="{{variationResultStatus && index === variationSelectedIndex}}" class="variation-border {{variationResultStatus}}"></view>
</view>
<view wx:if="{{variationImageLoaded[item.file_id]}}" class="selection-badge {{variationResultStatus === 'incorrect' && index === variationSelectedIndex ? 'incorrect' : (index === variationSelectedIndex ? 'selected' : 'unselected')}}">
<t-icon name="{{variationResultStatus === 'incorrect' && index === variationSelectedIndex ? 'close-circle' : 'check-circle'}}" size="36rpx" color="#fff" />
</view>
<view wx:if="{{variationResultStatus && index === variationSelectedIndex}}" class="variation-border {{variationResultStatus}}"></view>
<!-- <view class="variation-text">{{item.question}}</view> -->
</view>
</view>
</view>
</view>
<view class="conversation-content {{modeAnim}}" wx:if="{{questionMode === 'conversation' && conversationViewMode === 'setup'}}">
<view class="conversation-section">
<view class="conversation-label">难度选择</view>
<view class="conversation-tags">
<t-check-tag
wx:for="{{difficultyOptions}}"
wx:key="value"
variant="outline"
size="medium"
data-level="{{item.value}}"
checked="{{conversationDifficulty === item.value}}"
bindtap="selectConversationDifficulty"
content="{{ [conversationSceneLang === 'zh' ? item.label_zh : item.label_en] }}"
/>
</view>
</view>
<view class="conversation-section">
<view class="conversation-label">场景标签</view>
<view class="conversation-tags" wx:if="{{conversationSetting && conversationSetting.all_possible_scenes && conversationSetting.all_possible_scenes.length}}">
<t-check-tag
wx:for="{{conversationSetting.all_possible_scenes}}"
wx:key="scene_en"
variant="outline"
size="medium"
data-scene="{{item.scene_en}}"
checked="{{conversationSelectedScenesMap && conversationSelectedScenesMap[item.scene_en]}}"
bindtap="toggleConversationScene"
>
{{conversationSceneLang === 'zh' ? item.scene_zh : item.scene_en}}
</t-check-tag>
<t-check-tag
wx:for="{{conversationCustomScenes}}"
wx:key="key"
variant="outline"
size="medium"
data-scene="{{item.key}}"
checked="{{conversationSelectedScenesMap && conversationSelectedScenesMap[item.key]}}"
bindtap="toggleConversationScene"
>
<view class="custom-scene-tag">
<text class="custom-scene-text">{{item.text}}</text>
<t-icon name="close" size="24rpx" data-key="{{item.key}}" catchtap="onConversationCustomSceneDelete" />
</view>
<!-- <view class="variation-text">{{item.question}}</view> -->
</view>
</view>
</view>
</view>
<view class="conversation-content {{modeAnim}}" wx:if="{{questionMode === 'conversation' && conversationViewMode === 'setup'}}">
<view class="conversation-section">
<view class="conversation-label">难度选择</view>
<view class="conversation-tags">
<t-check-tag
wx:for="{{difficultyOptions}}"
wx:key="value"
variant="outline"
size="medium"
data-level="{{item.value}}"
checked="{{conversationDifficulty === item.value}}"
bindtap="selectConversationDifficulty"
content="{{ [conversationSceneLang === 'zh' ? item.label_zh : item.label_en] }}"
/>
</view>
</view>
<view class="conversation-section">
<view class="conversation-label">场景标签</view>
<view class="conversation-tags" wx:if="{{conversationSetting && conversationSetting.all_possible_scenes && conversationSetting.all_possible_scenes.length}}">
<t-check-tag
wx:for="{{conversationSetting.all_possible_scenes}}"
wx:key="scene_en"
variant="outline"
size="medium"
data-scene="{{item.scene_en}}"
checked="{{conversationSelectedScenesMap && conversationSelectedScenesMap[item.scene_en]}}"
bindtap="toggleConversationScene"
>
{{conversationSceneLang === 'zh' ? item.scene_zh : item.scene_en}}
</t-check-tag>
<t-check-tag
wx:for="{{conversationCustomScenes}}"
wx:key="key"
variant="outline"
size="medium"
data-scene="{{item.key}}"
checked="{{conversationSelectedScenesMap && conversationSelectedScenesMap[item.key]}}"
bindtap="toggleConversationScene"
>
<view class="custom-scene-tag">
<text class="custom-scene-text">{{item.text}}</text>
<t-icon name="close" size="24rpx" data-key="{{item.key}}" catchtap="onConversationCustomSceneDelete" />
</t-check-tag>
<view wx:if="{{conversationCustomSceneEditing}}" class="conversation-custom-scene-input-wrapper">
<input
class="conversation-custom-scene-input {{conversationCustomSceneOverLimit ? 'conversation-custom-scene-input-error' : ''}}"
value="{{conversationCustomSceneText}}"
placeholder="自定义场景"
maxlength="60"
focus="{{true}}"
bindinput="onConversationCustomSceneInput"
bindblur="onConversationCustomSceneBlur"
/>
</view>
</t-check-tag>
<view wx:if="{{conversationCustomSceneEditing}}" class="conversation-custom-scene-input-wrapper">
<input
class="conversation-custom-scene-input {{conversationCustomSceneOverLimit ? 'conversation-custom-scene-input-error' : ''}}"
value="{{conversationCustomSceneText}}"
placeholder="自定义场景"
maxlength="60"
focus="{{true}}"
bindinput="onConversationCustomSceneInput"
bindblur="onConversationCustomSceneBlur"
<t-check-tag
wx:if="{{!conversationCustomSceneEditing}}"
variant="outline"
size="medium"
bindtap="onConversationCustomSceneAdd"
>
+
</t-check-tag>
</view>
</view>
<view class="conversation-section">
<view class="conversation-label">事件标签</view>
<view class="conversation-tags" wx:if="{{conversationSetting && conversationSetting.all_possible_events && conversationSetting.all_possible_events.length}}">
<t-check-tag
wx:for="{{conversationSetting.all_possible_events}}"
wx:key="event_en"
variant="outline"
size="medium"
data-event="{{item.event_en}}"
checked="{{conversationSelectedEventsMap && conversationSelectedEventsMap[item.event_en]}}"
bindtap="toggleConversationEvent"
>
{{conversationSceneLang === 'zh' ? item.event_zh : item.event_en}}
</t-check-tag>
<t-check-tag
wx:for="{{conversationCustomEvents}}"
wx:key="key"
variant="outline"
size="medium"
data-event="{{item.key}}"
checked="{{conversationSelectedEventsMap && conversationSelectedEventsMap[item.key]}}"
bindtap="toggleConversationEvent"
>
<view class="custom-scene-tag">
<text class="custom-scene-text">{{item.text}}</text>
<t-icon name="close" size="24rpx" data-key="{{item.key}}" catchtap="onConversationCustomEventDelete" />
</view>
</t-check-tag>
<view wx:if="{{conversationCustomEventEditing}}" class="conversation-custom-scene-input-wrapper">
<input
class="conversation-custom-scene-input {{conversationCustomEventOverLimit ? 'conversation-custom-scene-input-error' : ''}}"
value="{{conversationCustomEventText}}"
placeholder="自定义事件"
maxlength="60"
focus="{{true}}"
bindinput="onConversationCustomEventInput"
bindblur="onConversationCustomEventBlur"
/>
</view>
<t-check-tag
wx:if="{{!conversationCustomEventEditing}}"
variant="outline"
size="medium"
bindtap="onConversationCustomEventAdd"
>
+
</t-check-tag>
</view>
</view>
<view class="conversation-section" wx:if="{{conversationSuggestedRoles && conversationSuggestedRoles.length}}">
<view class="conversation-label">角色扮演</view>
<view class="conversation-tags">
<block wx:for="{{conversationSuggestedRoles}}" wx:key="key" wx:for-index="idx">
<view style="display: flex; align-items: center;">
<t-check-tag
checked="{{selectedRole && selectedRole.roleIndex === idx && selectedRole.roleSide === 1}}"
bind:change="onRoleSelect"
data-index="{{idx}}"
data-side="{{1}}"
variant="outline"
size="medium"
>{{conversationSceneLang === 'zh' ? item.role1_zh : item.role1_en}}</t-check-tag>
<t-check-tag
checked="{{selectedRole && selectedRole.roleIndex === idx && selectedRole.roleSide === 2}}"
bind:change="onRoleSelect"
data-index="{{idx}}"
data-side="{{2}}"
variant="outline"
size="medium"
>{{conversationSceneLang === 'zh' ? item.role2_zh : item.role2_en}}</t-check-tag>
</view>
</block>
</view>
</view>
<view class="conversation-section">
<view class="conversation-label-row">
<text class="conversation-label">额外说明</text>
<text class="conversation-count">{{(conversationExtraNote && conversationExtraNote.length) || 0}}/200</text>
</view>
<view class="conversation-note-card">
<textarea
class="conversation-note-input"
placeholder="例如:描述一下图片中的人物关系或具体发生的事件,这将帮助 AI 更好地生成对话内容..."
maxlength="200"
value="{{conversationExtraNote}}"
bindinput="onConversationNoteInput"
/>
</view>
<t-check-tag
wx:if="{{!conversationCustomSceneEditing}}"
variant="outline"
size="medium"
bindtap="onConversationCustomSceneAdd"
>
+
</t-check-tag>
</view>
<view class="conversation-start-row">
<button class="conversation-start-btn" bindtap="onStartConversationTap">
开始对话
<t-icon name="chat" size="32rpx" style="margin-left: 12rpx;" />
</button>
</view>
</view>
<view class="conversation-section">
<view class="conversation-label">事件标签</view>
<view class="conversation-tags" wx:if="{{conversationSetting && conversationSetting.all_possible_events && conversationSetting.all_possible_events.length}}">
<t-check-tag
wx:for="{{conversationSetting.all_possible_events}}"
wx:key="event_en"
variant="outline"
size="medium"
data-event="{{item.event_en}}"
checked="{{conversationSelectedEventsMap && conversationSelectedEventsMap[item.event_en]}}"
bindtap="toggleConversationEvent"
<view class="conversation-content {{modeAnim}}" wx:if="{{questionMode === 'conversation' && conversationViewMode === 'chat'}}">
<block wx:if="{{conversationMessages && conversationMessages.length}}">
<view class="conversation-block {{item.role === 'user' ? 'user' : 'default'}}" wx:for="{{conversationMessages}}" wx:key="index"
>
{{conversationSceneLang === 'zh' ? item.event_zh : item.event_en}}
</t-check-tag>
<t-check-tag
wx:for="{{conversationCustomEvents}}"
wx:key="key"
variant="outline"
size="medium"
data-event="{{item.key}}"
checked="{{conversationSelectedEventsMap && conversationSelectedEventsMap[item.key]}}"
bindtap="toggleConversationEvent"
>
<view class="custom-scene-tag">
<text class="custom-scene-text">{{item.text}}</text>
<t-icon name="close" size="24rpx" data-key="{{item.key}}" catchtap="onConversationCustomEventDelete" />
</view>
</t-check-tag>
<view wx:if="{{conversationCustomEventEditing}}" class="conversation-custom-scene-input-wrapper">
<input
class="conversation-custom-scene-input {{conversationCustomEventOverLimit ? 'conversation-custom-scene-input-error' : ''}}"
value="{{conversationCustomEventText}}"
placeholder="自定义事件"
maxlength="60"
focus="{{true}}"
bindinput="onConversationCustomEventInput"
bindblur="onConversationCustomEventBlur"
<t-chat-message
role="{{item.role}}"
placement="{{item.role === 'user' ? 'right' : 'left'}}"
content="{{item.content}}"
/>
</view>
<t-check-tag
wx:if="{{!conversationCustomEventEditing}}"
variant="outline"
size="medium"
bindtap="onConversationCustomEventAdd"
>
+
</t-check-tag>
</view>
</view>
<view class="conversation-section" wx:if="{{conversationSuggestedRoles && conversationSuggestedRoles.length}}">
<view class="conversation-label">角色扮演</view>
<view class="conversation-tags">
<block wx:for="{{conversationSuggestedRoles}}" wx:key="key" wx:for-index="idx">
<view style="display: flex; align-items: center;">
<t-check-tag
checked="{{selectedRole && selectedRole.roleIndex === idx && selectedRole.roleSide === 1}}"
bind:change="onRoleSelect"
data-index="{{idx}}"
data-side="{{1}}"
variant="outline"
size="medium"
>{{conversationSceneLang === 'zh' ? item.role1_zh : item.role1_en}}</t-check-tag>
<t-check-tag
checked="{{selectedRole && selectedRole.roleIndex === idx && selectedRole.roleSide === 2}}"
bind:change="onRoleSelect"
data-index="{{idx}}"
data-side="{{2}}"
variant="outline"
size="medium"
>{{conversationSceneLang === 'zh' ? item.role2_zh : item.role2_en}}</t-check-tag>
</view>
</block>
</block>
<view class="conversation-block" wx:if="{{replyLoading}}">
<t-chat-loading animation="dots" />
</view>
<view id="bottom-anchor" style="height: 1rpx;"></view>
</view>
<view class="conversation-section">
<view class="conversation-label-row">
<text class="conversation-label">额外说明</text>
<text class="conversation-count">{{(conversationExtraNote && conversationExtraNote.length) || 0}}/200</text>
</view>
<view class="conversation-note-card">
<textarea
class="conversation-note-input"
placeholder="例如:描述一下图片中的人物关系或具体发生的事件,这将帮助 AI 更好地生成对话内容..."
maxlength="200"
value="{{conversationExtraNote}}"
bindinput="onConversationNoteInput"
/>
</view>
<view class="submit-row" wx:if="{{questionMode !== 'conversation'}}">
<button class="submit-btn" bindtap="onSubmitTap" disabled="{{submitDisabled}}" wx:if="{{retryDisabled}}">提交</button>
<button class="submit-btn" bindtap="onRetryTap" disabled="{{retryDisabled}}" wx:else>重试</button>
</view>
<view class="conversation-start-row">
<button class="conversation-start-btn" bindtap="onStartConversationTap">
开始对话
<t-icon name="chat" size="32rpx" style="margin-left: 12rpx;" />
</button>
</view>
</view>
<view class="conversation-content {{modeAnim}}" wx:if="{{questionMode === 'conversation' && conversationViewMode === 'chat'}}">
<block wx:if="{{conversationMessages && conversationMessages.length}}">
<view class="conversation-block {{item.role === 'user' ? 'user' : 'default'}}" wx:for="{{conversationMessages}}" wx:key="index"
>
<t-chat-message
role="{{item.role}}"
placement="{{item.role === 'user' ? 'right' : 'left'}}"
content="{{item.content}}"
/>
</view>
</block>
<view class="conversation-block" wx:if="{{replyLoading}}">
<t-chat-loading animation="dots" />
</view>
<view id="bottom-anchor" style="height: 1rpx;"></view>
</view>
<view class="submit-row" wx:if="{{questionMode !== 'conversation'}}">
<button class="submit-btn" bindtap="onSubmitTap" disabled="{{submitDisabled}}" wx:if="{{retryDisabled}}">提交</button>
<button class="submit-btn" bindtap="onRetryTap" disabled="{{retryDisabled}}" wx:else>重试</button>
</scroll-view>
</view>
</scroll-view>
</view>
<view class="bottom-bar {{contentVisible ? 'show' : ''}}" wx:if="{{questionMode !== 'conversation'}}">
@@ -280,12 +282,7 @@
<t-icon name="fact-check" class="bottom-btn {{resultDisplayed ? '' : 'disabled'}}" size="48rpx" bind:tap="onScoreTap" />
<t-icon name="{{nextButtonIcon || 'chevron-right'}}" class="bottom-btn {{(qaList && (currentIndex >= qaList.length - 1)) ? 'disabled' : ''}}" size="48rpx" bind:tap="onNextTap" />
</view>
<t-drawer
visible="{{visible}}"
placement="right"
bind:overlay-click="overlayClick"
>
<t-drawer visible="{{historyVisible}}" placement="left" bind:visible-change="onHistoryDrawerClose" close-btn="{{true}}">
<scroll-view scroll-y class="history-drawer-scroll" bindscrolltolower="onHistoryScrollBottom">
<view class="history-list">
<t-cell

View File

@@ -24,13 +24,20 @@
@keyframes fadeInUp { from { opacity: 0; transform: translate3d(0, 12rpx, 0) } to { opacity: 1; transform: translate3d(0, 0, 0) } }
@keyframes fadeOutDown { from { opacity: 1; transform: translate3d(0, 0, 0) } to { opacity: 0; transform: translate3d(0, 12rpx, 0) } }
.question-scroll {
.question-scroll-wrapper {
flex: 1;
height: 0;
min-height: 0;
display: block;
overflow: hidden;
/* padding-bottom: calc(110rpx + env(safe-area-inset-bottom)); */
/* transition: padding-bottom 0.3s ease; */
transition: margin-bottom 0.3s ease;
}
.inner-scroll {
height: 100%;
width: 100%;
}
.chat-mode-scroll {
/* padding-bottom: calc(110rpx + env(safe-area-inset-bottom)); */
margin-bottom: calc(110rpx + env(safe-area-inset-bottom));