diff --git a/src/components/location-dialog/index.less b/src/components/location-dialog/index.less index 2a69a6a..49feafd 100644 --- a/src/components/location-dialog/index.less +++ b/src/components/location-dialog/index.less @@ -16,6 +16,7 @@ &__confirm-button { .button(@width: 360px, @height: 72px, @fontSize: 28px, @fontWeight: 400, @borderRadius: 44px); margin-top: 40px; + margin-bottom: 40px; } // &__cancel-button { @@ -31,8 +32,4 @@ // border-color: transparent // } // } - - &__checkbox { - margin-top: 40px; - } } diff --git a/src/components/location-dialog/index.tsx b/src/components/location-dialog/index.tsx index c75bee3..a989794 100644 --- a/src/components/location-dialog/index.tsx +++ b/src/components/location-dialog/index.tsx @@ -1,10 +1,8 @@ import { Button } from '@tarojs/components'; import { Dialog } from '@taroify/core'; -import { useCallback, useState } from 'react'; -import { ProtocolPrivacyCheckbox } from '@/components/protocol-privacy'; -import Toast from '@/utils/toast'; +import { ProtocolPrivacy } from '@/components/protocol-privacy'; import './index.less'; @@ -18,28 +16,15 @@ const PREFIX = 'location-dialog'; export default function LocationDialog(props: IProps) { const { open, onClick, onClose } = props; - const [checked, setChecked] = useState(false); - - const handleTipCheck = useCallback(() => { - Toast.info('请先阅读并同意协议'); - }, []); - return (
{`我们需要获取您的位置信息\n以便推荐附近的通告或主播`}
- {!checked && ( - - )} - {checked && ( - - )} - + +
diff --git a/src/constants/app.ts b/src/constants/app.ts index 00f2495..0c2a0cd 100644 --- a/src/constants/app.ts +++ b/src/constants/app.ts @@ -55,6 +55,7 @@ export enum PageUrl { JobSelectMyPublish = 'pages/job-select-my-publish/index', GroupJob = 'pages/group-job/index', CitySearch = 'pages/search-city/index', + CitySearchProfile = 'pages/search-city-profile/index', UserInfo = 'pages/user-info/index', UserBatchPublish = 'pages/user-batch-publish/index', MyDeclaration = 'pages/my-declaration/index', diff --git a/src/fragments/profile/intention/index.tsx b/src/fragments/profile/intention/index.tsx index d231aa7..d80ef3a 100644 --- a/src/fragments/profile/intention/index.tsx +++ b/src/fragments/profile/intention/index.tsx @@ -77,7 +77,8 @@ function ProfileIntentionFragment(props: IProps, ref) { const handleClickAddCity = useCallback(() => { const currentCity = getCurrentCity(); - navigateTo(PageUrl.CitySearch, { city: currentCity, source: OpenSource.AddIndentCity }); + realtimeLogger.info('handleClickAddCity', OpenSource.AddIndentCity); + navigateTo(PageUrl.CitySearchProfile, { city: currentCity, source: OpenSource.AddIndentCity }); }, []); const handleSelectCity = useCallback( @@ -85,9 +86,9 @@ function ProfileIntentionFragment(props: IProps, ref) { log('handleSelectCity', data); realtimeLogger.info('handleSelectCity', data); const { openSource, cityCode: code } = data; - if (openSource !== OpenSource.AddIndentCity) { - return; - } + // if (openSource !== OpenSource.AddIndentCity) { + // return; + // } const newCodes = [...new Set([...cityCodes, code])]; setCityCodes(newCodes); }, diff --git a/src/hooks/use-config.tsx b/src/hooks/use-config.tsx index 64d41a1..d037094 100644 --- a/src/hooks/use-config.tsx +++ b/src/hooks/use-config.tsx @@ -80,6 +80,7 @@ export const APP_CONFIG: AppConfigType = { PageUrl.UserInfo, PageUrl.UserBatchPublish, PageUrl.CitySearch, + PageUrl.CitySearchProfile, PageUrl.MyDeclaration, PageUrl.MyPublish, // PageUrl.FollowGroup, diff --git a/src/pages/search-city-profile/index.config.ts b/src/pages/search-city-profile/index.config.ts new file mode 100644 index 0000000..6eae8a3 --- /dev/null +++ b/src/pages/search-city-profile/index.config.ts @@ -0,0 +1,4 @@ +export default definePageConfig({ + navigationBarTitleText: '选择城市', + disableScroll: true, +}); diff --git a/src/pages/search-city-profile/index.less b/src/pages/search-city-profile/index.less new file mode 100644 index 0000000..ea36334 --- /dev/null +++ b/src/pages/search-city-profile/index.less @@ -0,0 +1,123 @@ +@import '@/styles/variables.less'; + +.search-city-profile { + background: #FFF; + + &__position-title { + font-size: 24px; + color: @blColorG1; + padding: 0 24px; + margin-top: 18px; + } + + &__position-city { + font-size: 30px; + font-weight: bold; + color: @blColor; + padding: 0 24px; + margin-top: 18px; + } + + &__hot-city-title { + height: 48px; + font-size: 24px; + line-height: 48px; + padding: 0 24px; + color: #999; + background: #f2f5f7; + margin-top: 18px; + } + + &__hot-city-container { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-content: space-between; + width: 630px; + padding: 12px 90px 26px 30px; + background: #FFFFFF; + } + + &__hot-city-item { + width: 140px; + height: 58px; + font-size: 28px; + line-height: 58px; + text-align: center; + border-radius: 58px; + border: 2px solid @blColorG1; + margin-top: 18px; + } + + &__indexes-list { + width: 100%; + /* 兼容 iOS < 11.2 */ + padding-bottom: constant(safe-area-inset-bottom); + /* 兼容 iOS >= 11.2 */ + padding-bottom: env(safe-area-inset-bottom); + } + + &__indexes-fragment {} + + &__indexes-anchor { + height: 48px; + font-size: 24px; + line-height: 48px; + padding: 0 24px; + color: @blColorG1; + background: #f2f5f7; + } + + &__indexes-cell { + position: relative; + font-size: 28px; + padding: 30px 24px; + color: @blColor; + + &::after { + content: ''; + position: absolute; + border-bottom: 1rpx solid #eaeef1; + transform: scaleY(0.5); + bottom: 0; + right: 0; + left: 24px; + } + } + + &__indexes-bar { + width: 44rpx; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + position: fixed; + right: 10px; + } + + &__indexes-bar-item { + font-size: 22px; + color: @blColor; + white-space: nowrap; + display: flex; + align-items: center; + justify-content: center; + } + + &__indexes-index-alert { + position: absolute; + z-index: 20; + width: 160px; + height: 160px; + left: 50%; + top: 50%; + margin-left: -80px; + margin-top: -80px; + border-radius: 80px; + text-align: center; + line-height: 160px; + font-size: 70px; + color: #FFFFFF; + background-color: rgba(0, 0, 0, 0.5); + } +} diff --git a/src/pages/search-city-profile/index.tsx b/src/pages/search-city-profile/index.tsx new file mode 100644 index 0000000..fff0b3f --- /dev/null +++ b/src/pages/search-city-profile/index.tsx @@ -0,0 +1,232 @@ +import { BaseEventOrig, InputProps, ScrollView } from '@tarojs/components'; +import Taro, { useLoad } from '@tarojs/taro'; + +import { Search } from '@taroify/core'; +import { useCallback, useEffect, useRef, useState } from 'react'; + +import { EventName, OpenSource } from '@/constants/app'; +import { CITY_CODE_TO_NAME_MAP, CITY_INDEXES_LIST } from '@/constants/city'; +import { logWithPrefix } from '@/utils/common'; +import { getPageQuery, navigateBack } from '@/utils/route'; + +import './index.less'; + +interface Item { + cityCode: number | string; + cityName: string; + keyword: string; +} + +const PREFIX = 'search-city-profile'; +const HOT_CITY = [ + { cityCode: 110100, cityName: '北京' }, + { cityCode: 310100, cityName: '上海' }, + { cityCode: 440100, cityName: '广州' }, + { cityCode: 440300, cityName: '深圳' }, + { cityCode: 330100, cityName: '杭州' }, + { cityCode: 430100, cityName: '长沙' }, + { cityCode: 420100, cityName: '武汉' }, + { cityCode: 350200, cityName: '厦门' }, + { cityCode: 610100, cityName: '西安' }, + { cityCode: 410100, cityName: '郑州' }, + { cityCode: 510100, cityName: '成都' }, + { cityCode: 340100, cityName: '合肥' }, +]; +const OFFSET_INDEX_SIZE = 2; +const log = logWithPrefix(PREFIX); +const realtimeLogger = Taro.getRealtimeLogManager(); +realtimeLogger.tag(PREFIX); +const useHeight = () => { + const [winHeight, setWinHeight] = useState(0); + const [indexItemHeight, setIndexItemHeight] = useState(0); + + useEffect(() => { + const windowInfo = Taro.getWindowInfo(); + const windowHeight = windowInfo.windowHeight; + setWinHeight(windowHeight); + // 上下预留两个选项高度的空白 + setIndexItemHeight(Math.floor(windowHeight / (26 + OFFSET_INDEX_SIZE * 2))); + }, []); + + return [winHeight, indexItemHeight]; +}; + +export default function SearchCity() { + const [winHeight, indexItemHeight] = useHeight(); + const [currentCity, setCurrentCity] = useState(''); + const [touchAnchor, setTouchAnchor] = useState(); + const [touchMoving, setTouchMoving] = useState(false); + const [searchResult, setSearchResult] = useState([]); + const openSourceRef = useRef(OpenSource.None); + const showSearchList = searchResult.length > 0; + + const handleSearchChange = useCallback((event: BaseEventOrig) => { + const value = event.detail.value; + log('handleSearchChange', value); + if (!value) { + setSearchResult([]); + return; + } + const result: Item[] = []; + CITY_INDEXES_LIST.forEach(obj => { + obj.data.forEach(city => { + if (city.keyword.includes(value.toLocaleUpperCase())) { + result.push({ ...city }); + } + }); + }); + setSearchResult(result); + }, []); + + const handleSelectCity = useCallback((e: React.MouseEvent) => { + const cityCode = e.currentTarget.dataset.code; + realtimeLogger.info('handleSelectCity openSource', openSourceRef.current); + Taro.eventCenter.trigger(EventName.SELECT_CITY, { openSource: openSourceRef.current, cityCode: String(cityCode) }); + navigateBack(1); + }, []); + + const handleTouchStart = useCallback( + (e: React.TouchEvent) => { + const pageY = e.touches[0].pageY; + const index = Math.floor(pageY / indexItemHeight) - OFFSET_INDEX_SIZE; + if (index < 0 || index >= CITY_INDEXES_LIST.length) { + return; + } + const item = CITY_INDEXES_LIST[index]; + if (item) { + setTouchMoving(true); + setTouchAnchor(item.letter); + } + }, + [indexItemHeight] + ); + + const handleTouchMove = useCallback( + (e: React.TouchEvent) => { + const pageY = e.touches[0].pageY; + const index = Math.floor(pageY / indexItemHeight) - OFFSET_INDEX_SIZE; + if (index < 0 || index >= CITY_INDEXES_LIST.length) { + return; + } + const item = CITY_INDEXES_LIST[index]; + item && setTouchAnchor(item.letter); + }, + [indexItemHeight] + ); + + const handleTouchEnd = useCallback((e: React.TouchEvent) => { + e.stopPropagation(); + setTouchMoving(false); + log('touch end'); + }, []); + + const handleClickAnchor = useCallback((anchor: string) => { + setTouchAnchor(anchor); + log('click anchor', anchor); + }, []); + + useLoad(() => { + const query = getPageQuery<{ city: string; source: OpenSource }>(); + log('query', query); + const { city: cityCode, source: openSource } = query; + realtimeLogger.info('searchCity query source', openSource); + if (!cityCode) { + return; + } + setCurrentCity(cityCode); + openSourceRef.current = openSource || OpenSource.None; + }); + + return ( +
+ + + {showSearchList && ( +
+ {searchResult.map(city => ( +
+ {city.cityName} +
+ ))} +
+ )} + {!showSearchList && ( +
+
当前城市
+
{CITY_CODE_TO_NAME_MAP.get(currentCity)}
+
热门城市
+
+ {HOT_CITY.map(city => ( +
+ {city.cityName} +
+ ))} +
+
+ {CITY_INDEXES_LIST.map(item => { + return ( +
+
+ {item.letter} +
+ {item.data.map(city => ( +
+ {city.cityName} +
+ ))} +
+ ); + })} +
+
+ )} +
+
+ {!showSearchList && ( +
+ {CITY_INDEXES_LIST.map(item => { + return ( +
handleClickAnchor(item.letter)} + > + {item.letter} +
+ ); + })} +
+ )} + {touchAnchor && touchMoving &&
{touchAnchor}
} +
+
+ ); +} diff --git a/src/pages/search-city/index.tsx b/src/pages/search-city/index.tsx index c038dbf..2c0a705 100644 --- a/src/pages/search-city/index.tsx +++ b/src/pages/search-city/index.tsx @@ -34,7 +34,8 @@ const HOT_CITY = [ ]; const OFFSET_INDEX_SIZE = 2; const log = logWithPrefix(PREFIX); - +const realtimeLogger = Taro.getRealtimeLogManager(); +realtimeLogger.tag(PREFIX); const useHeight = () => { const [winHeight, setWinHeight] = useState(0); const [indexItemHeight, setIndexItemHeight] = useState(0); @@ -127,6 +128,7 @@ export default function SearchCity() { const query = getPageQuery<{ city: string; source: OpenSource }>(); log('query', query); const { city: cityCode, source: openSource } = query; + realtimeLogger.info('searchCity query source', openSource); if (!cityCode) { return; }