Files
miniprogram-1/miniprogram/pages/scene_sentence/scene_sentence.wxml
2025-12-30 20:37:59 +08:00

160 lines
7.5 KiB
Plaintext

<view class="scene-sentence-container">
<view wx:if="{{loadingMaskVisible}}" class="page-loading-mask">
<view class="loading-center">
<view class="scanner scanner-visible">
<view class="star star1"></view>
<view class="star star2"></view>
<view class="star star3"></view>
</view>
<view class="status-text">{{loadingLabel}}{{loadingDots}}</view>
</view>
</view>
<view class="container {{contentVisible ? 'fade-in' : 'fade-out'}}" wx:if="{{scene && scene.list && scene.list.length > 0}}">
<block wx:if="{{scene.list[currentIndex]}}">
<view class="sentence-header">
<view class="sentence-en sentence-content-wrapper">
<view wx:for="{{englishWords}}" wx:for-item="w" wx:for-index="i" wx:key="i" class="sentence-word" style="{{i === 0 ? 'text-transform: capitalize;' : ''}}" data-word="{{w}}" data-index="{{i}}" bindtap="onWordTap">{{w}}</view>
</view>
<text class="sentence-zh">{{scene.list[currentIndex].sentenceZh}}</text>
</view>
<scroll-view class="sentence-body" scroll-y="true" scroll-with-animation="true">
<view class="tags-wrap">
<t-tag wx:for="{{scene.list[currentIndex].functionTags}}" wx:key="idx" variant="light"><text>#</text>{{item}}</t-tag>
</view>
<view class="tip-card">
<view class="tip-title">
<t-icon name="info-circle" size="40rpx" />
<text>发音提示</text>
</view>
<view class="tip-content">
<text>{{scene.list[currentIndex].pronunciationTip}}</text>
</view>
<view class="fluency-hack" wx:if="{{scene.list[currentIndex].fluencyHacks}}">
<view class="hack-title">
<t-icon name="chat-bubble-smile" size="32rpx" />
<text>技巧</text>
</view>
<view class="hack-content">
<text>{{scene.list[currentIndex].fluencyHacks}}</text>
</view>
</view>
</view>
<view class="tip-card">
<view class="tip-title">
<t-icon name="chat-bubble-error" size="40rpx" />
<text>常见错误</text>
</view>
<view class="tip-content">
<text wx:for="{{commonMistakes}}" wx:for-index="i" wx:key="idx" class="mistake-item ">{{item}}</text>
</view>
<!-- <view class="fluency-hack" wx:if="{{scene.list[currentIndex].fluencyHacks}}">
<view class="hack-title">
<t-icon name="notification-error" size="32rpx" />
<text>注意事项</text>
</view>
<view class="hack-content">
<text>{{scene.list[currentIndex].avoidScenarios}}</text>
</view>
</view> -->
</view>
<view class="section-title">
<text>相似句型</text>
</view>
<view class="mistake-card" wx:if="{{pragmaticAlternative && pragmaticAlternative.length > 0}}">
<view class="mistake-list">
<text wx:for="{{pragmaticAlternative}}" wx:for-index="i" wx:key="idx" class="mistake-item ">{{item}}</text>
</view>
</view>
<view class="section-title">
<text>搭话</text>
</view>
<view class="mistake-card" wx:if="{{responsePairs && responsePairs.length > 0}}">
<view class="mistake-list">
<text wx:for="{{responsePairs}}" wx:for-index="i" wx:key="idx" class="mistake-item ">{{item}}</text>
</view>
</view>
<view class="section-title">
<text>核心词汇</text>
<text class="section-count">{{scene.list[currentIndex].coreVocab.length}} words</text>
</view>
<view class="core-vocab">
<t-tag class="core-vocab-tag" wx:for="{{scene.list[currentIndex].coreVocab}}" wx:for-index="i" wx:key="word" variant="light" theme="primary" data-word="{{item}}" bindtap="onWordTap">{{item}} {{scene.list[currentIndex].coreVocabDesc[i]}}</t-tag>
</view>
<view class="section-title">
<text>搭配用法</text>
</view>
<view class="collocations">
<t-tag wx:for="{{scene.list[currentIndex].collocations}}" wx:key="idx" variant="light" theme="primary">{{item}}</t-tag>
</view>
<!-- <view class="scene-explain">
<text>{{scene.list[currentIndex].sceneExplanation}}</text>
</view> -->
<view class="sentence-tips">上述内容由AI生成</view>
</scroll-view>
</block>
</view>
<view class="highlight-area {{overlayVisible ? 'show' : ''}}" catchtouchstart="noop" catchtouchmove="noop" catchtouchend="noop">
<view wx:for="{{highlightWords}}" wx:key="index"
class="overlay-word {{highlightShow ? 'show' : ''}} {{highlightZoom ? 'zoom' : ''}}"
style="left: {{item.left}}px; top: {{item.top}}px; width: {{item.width}}px; height: {{item.height}}px; {{item.transform ? ('transform: ' + item.transform) : ''}}">
<view class="overlay-text {{analizing ? 'loading-shimmer' : ''}}" style="animation-delay: {{index * 200}}ms; {{index === 0 ? 'text-transform: capitalize;' : ''}}">{{item.text}}</view>
</view>
</view>
<view wx:if="{{isRecording}}" class="recording-mask" catchtouchstart="noop" catchtouchmove="noop" catchtouchend="noop"></view>
<view class="bottom-bar {{buttonsVisible ? 'show' : ''}}">
<t-icon name="chevron-left" class="bottom-btn {{currentIndex <= 0 ? 'disabled' : ''}}" size="48rpx" bind:tap="onPrevTap" />
<t-icon name="{{isPlaying ? 'pause' : 'play'}}" class="bottom-btn" size="48rpx" bind:tap="playStandardVoice" />
<view class="mic-wrap" bind:longpress="handleRecordStart" bind:touchend="handleRecordEnd" bind:touchcancel="handleRecordEnd">
<t-icon name="microphone-1" class="microphone {{isRecording ? 'recording' : 'bottom-btn'}}" size="48rpx" />
<view wx:if="{{isRecording}}" class="mic">
<view class="mic-shadow"></view>
</view>
</view>
<t-icon name="fact-check" class="bottom-btn {{(hasScoreInfo && !isRecording) ? '' : 'disabled'}}" size="48rpx" bind:tap="onScoreTap" />
<t-icon name="chevron-right" class="bottom-btn {{(scene.list && (currentIndex >= scene.list.length - 1)) ? 'disabled' : ''}}" size="48rpx" bind:tap="onNextTap" />
</view>
<score-modal
wx:if="{{isScoreModalOpen && hasScoreInfo}}"
visible="{{scoreModalVisible}}"
hasScoreInfo="{{hasScoreInfo}}"
sentence="{{currentSentence}}"
totalScore="{{displayTotalScore}}"
accuracyScore="{{displayAccuracyScore}}"
completenessScore="{{displayCompletenessScore}}"
fluencyScore="{{displayFluencyScore}}"
circleProgressStyle="{{circleProgressStyle}}"
accuracyCircleStyle="{{accuracyCircleStyle}}"
completenessCircleStyle="{{completenessCircleStyle}}"
fluencyCircleStyle="{{fluencyCircleStyle}}"
wordScores="{{wordScores}}"
bind:close="onCloseScoreModal"
bind:play="playAssessmentVoice"
/>
<word-dictionary
visible="{{showDictPopup}}"
expanded="{{showDictExtended}}"
loading="{{dictLoading}}"
wordDict="{{wordDict}}"
showBackIcon="{{showBackIcon}}"
prototypeWord="{{prototypeWord}}"
forceHidePrototype="{{forceHidePrototype}}"
isWordEmptyResult="{{isWordEmptyResult}}"
id="wordDict"
dictDefaultTabValue="{{dictDefaultTabValue}}"
bind:close="handleDictClose"
bind:more="handleDictMore"
bind:back="handleBackToPreviousWord"
bind:wordTap="onWordTap"
/>
<view class="word-popup-mask" wx:if="{{showDictPopup}}" bindtap="handleDictClose"></view>
</view>